|
@@ -2,6 +2,7 @@
|
|
| 2 |
|
| 3 |
import (
|
| 4 |
"context"
|
|
|
|
| 5 |
"encoding/json"
|
| 6 |
"errors"
|
| 7 |
"fmt"
|
|
@@ -67,6 +71,9 @@
|
|
| 67 |
srv *grpc.Server
|
| 68 |
ctx context.Context
|
| 69 |
exit context.CancelFunc
|
|
|
|
|
|
|
|
|
|
| 70 |
}
|
| 71 |
|
| 72 |
// New creates a new aggregator.
|
|
@@ -75,6 +82,8 @@
|
|
| 75 |
stateInterface stateInterface,
|
| 76 |
ethTxManager ethTxManager,
|
| 77 |
etherman etherman,
|
|
|
|
|
|
|
| 78 |
) (Aggregator, error) {
|
| 79 |
var profitabilityChecker aggregatorTxProfitabilityChecker
|
| 80 |
switch cfg.TxProfitabilityCheckerType {
|
|
@@ -96,6 +105,9 @@
|
|
| 96 |
TimeCleanupLockedProofs: cfg.CleanupLockedProofsInterval,
|
| 97 |
|
| 98 |
finalProof: make(chan finalProofMsg),
|
|
|
|
|
|
|
|
|
|
| 99 |
}
|
| 100 |
|
| 101 |
return a, nil
|
|
@@ -269,34 +281,139 @@
|
|
| 269 |
|
| 270 |
log.Infof("Final proof inputs: NewLocalExitRoot [%#x], NewStateRoot [%#x]", inputs.NewLocalExitRoot, inputs.NewStateRoot)
|
| 271 |
|
| 272 |
-
|
| 273 |
-
|
| 274 |
-
|
| 275 |
-
|
| 276 |
-
|
| 277 |
-
|
| 278 |
-
|
| 279 |
-
|
| 280 |
-
|
| 281 |
-
err = a.EthTxManager.Add(ctx, ethTxManagerOwner, monitoredTxID, sender, to, nil, data, a.cfg.GasOffset, nil)
|
| 282 |
-
if err != nil {
|
| 283 |
-
mTxLogger := ethtxmanager.CreateLogger(ethTxManagerOwner, monitoredTxID, sender, to)
|
| 284 |
-
mTxLogger.Errorf("Error to add batch verification tx to eth tx manager: %v", err)
|
| 285 |
-
a.handleFailureToAddVerifyBatchToBeMonitored(ctx, proof)
|
| 286 |
-
continue
|
| 287 |
}
|
| 288 |
|
| 289 |
-
// process monitored batch verifications before starting a next cycle
|
| 290 |
-
a.EthTxManager.ProcessPendingMonitoredTxs(ctx, ethTxManagerOwner, func(result ethtxmanager.MonitoredTxResult, dbTx pgx.Tx) {
|
| 291 |
-
a.handleMonitoredTxResult(result)
|
| 292 |
-
}, nil)
|
| 293 |
-
|
| 294 |
a.resetVerifyProofTime()
|
| 295 |
a.endProofVerification()
|
| 296 |
}
|
| 297 |
}
|
| 298 |
}
|
| 299 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 300 |
func (a *Aggregator) handleFailureToAddVerifyBatchToBeMonitored(ctx context.Context, proof *state.Proof) {
|
| 301 |
log := log.WithFields("proofId", proof.ProofID, "batches", fmt.Sprintf("%d-%d", proof.BatchNumber, proof.BatchNumberFinal))
|
| 302 |
proof.GeneratingSince = nil
|
|
@@ -1021,7 +1138,7 @@
|
|
| 1021 |
if err != nil {
|
| 1022 |
return nil, err
|
| 1023 |
}
|
| 1024 |
-
leaves, err := a.State.
|
| 1025 |
if err != nil {
|
| 1026 |
return nil, err
|
| 1027 |
}
|
|
|
|
| 2 |
|
| 3 |
import (
|
| 4 |
"context"
|
| 5 |
+
"crypto/ecdsa"
|
| 6 |
"encoding/json"
|
| 7 |
"errors"
|
| 8 |
"fmt"
|
|
|
|
| 71 |
srv *grpc.Server
|
| 72 |
ctx context.Context
|
| 73 |
exit context.CancelFunc
|
| 74 |
+
|
| 75 |
+
AggLayerClient client.ClientInterface
|
| 76 |
+
sequencerPrivateKey *ecdsa.PrivateKey
|
| 77 |
}
|
| 78 |
|
| 79 |
// New creates a new aggregator.
|
|
|
|
| 82 |
stateInterface stateInterface,
|
| 83 |
ethTxManager ethTxManager,
|
| 84 |
etherman etherman,
|
| 85 |
+
agglayerClient client.ClientInterface,
|
| 86 |
+
sequencerPrivateKey *ecdsa.PrivateKey,
|
| 87 |
) (Aggregator, error) {
|
| 88 |
var profitabilityChecker aggregatorTxProfitabilityChecker
|
| 89 |
switch cfg.TxProfitabilityCheckerType {
|
|
|
|
| 105 |
TimeCleanupLockedProofs: cfg.CleanupLockedProofsInterval,
|
| 106 |
|
| 107 |
finalProof: make(chan finalProofMsg),
|
| 108 |
+
|
| 109 |
+
AggLayerClient: agglayerClient,
|
| 110 |
+
sequencerPrivateKey: sequencerPrivateKey,
|
| 111 |
}
|
| 112 |
|
| 113 |
return a, nil
|
|
|
|
| 281 |
|
| 282 |
log.Infof("Final proof inputs: NewLocalExitRoot [%#x], NewStateRoot [%#x]", inputs.NewLocalExitRoot, inputs.NewStateRoot)
|
| 283 |
|
| 284 |
+
switch a.cfg.SettlementBackend {
|
| 285 |
+
case AggLayer:
|
| 286 |
+
if success := a.settleWithAggLayer(ctx, proof, inputs); !success {
|
| 287 |
+
continue
|
| 288 |
+
}
|
| 289 |
+
default:
|
| 290 |
+
if success := a.settleDirect(ctx, proof, inputs); !success {
|
| 291 |
+
continue
|
| 292 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 293 |
}
|
| 294 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 295 |
a.resetVerifyProofTime()
|
| 296 |
a.endProofVerification()
|
| 297 |
}
|
| 298 |
}
|
| 299 |
}
|
| 300 |
|
| 301 |
+
func (a *Aggregator) settleDirect(
|
| 302 |
+
ctx context.Context,
|
| 303 |
+
proof *state.Proof,
|
| 304 |
+
inputs ethmanTypes.FinalProofInputs,
|
| 305 |
+
) (success bool) {
|
| 306 |
+
// add batch verification to be monitored
|
| 307 |
+
sender := common.HexToAddress(a.cfg.SenderAddress)
|
| 308 |
+
|
| 309 |
+
to, data, err := a.Ethman.BuildTrustedVerifyBatchesTxData(
|
| 310 |
+
proof.BatchNumber-1,
|
| 311 |
+
proof.BatchNumberFinal,
|
| 312 |
+
&inputs,
|
| 313 |
+
sender,
|
| 314 |
+
)
|
| 315 |
+
if err != nil {
|
| 316 |
+
log.Errorf("Error estimating batch verification to add to eth tx manager: %v", err)
|
| 317 |
+
a.handleFailureToAddVerifyBatchToBeMonitored(ctx, proof)
|
| 318 |
+
|
| 319 |
+
return false
|
| 320 |
+
}
|
| 321 |
+
|
| 322 |
+
monitoredTxID := buildMonitoredTxID(proof.BatchNumber, proof.BatchNumberFinal)
|
| 323 |
+
err = a.EthTxManager.Add(
|
| 324 |
+
ctx,
|
| 325 |
+
ethTxManagerOwner,
|
| 326 |
+
monitoredTxID,
|
| 327 |
+
sender,
|
| 328 |
+
to,
|
| 329 |
+
nil,
|
| 330 |
+
data,
|
| 331 |
+
a.cfg.GasOffset,
|
| 332 |
+
nil,
|
| 333 |
+
)
|
| 334 |
+
if err != nil {
|
| 335 |
+
mTxLogger := ethtxmanager.CreateLogger(ethTxManagerOwner, monitoredTxID, sender, to)
|
| 336 |
+
mTxLogger.Errorf("Error to add batch verification tx to eth tx manager: %v", err)
|
| 337 |
+
a.handleFailureToAddVerifyBatchToBeMonitored(ctx, proof)
|
| 338 |
+
|
| 339 |
+
return false
|
| 340 |
+
}
|
| 341 |
+
|
| 342 |
+
// process monitored batch verifications before starting a next cycle
|
| 343 |
+
a.EthTxManager.ProcessPendingMonitoredTxs(
|
| 344 |
+
ctx,
|
| 345 |
+
ethTxManagerOwner,
|
| 346 |
+
func(result ethtxmanager.MonitoredTxResult, dbTx pgx.Tx) {
|
| 347 |
+
a.handleMonitoredTxResult(result)
|
| 348 |
+
},
|
| 349 |
+
nil,
|
| 350 |
+
)
|
| 351 |
+
|
| 352 |
+
return true
|
| 353 |
+
}
|
| 354 |
+
|
| 355 |
+
func (a *Aggregator) settleWithAggLayer(
|
| 356 |
+
ctx context.Context,
|
| 357 |
+
proof *state.Proof,
|
| 358 |
+
inputs ethmanTypes.FinalProofInputs,
|
| 359 |
+
) (success bool) {
|
| 360 |
+
proofStrNo0x := strings.TrimPrefix(inputs.FinalProof.Proof, "0x")
|
| 361 |
+
proofBytes := common.Hex2Bytes(proofStrNo0x)
|
| 362 |
+
tx := tx.Tx{
|
| 363 |
+
LastVerifiedBatch: agglayerTypes.ArgUint64(proof.BatchNumber - 1),
|
| 364 |
+
NewVerifiedBatch: agglayerTypes.ArgUint64(proof.BatchNumberFinal),
|
| 365 |
+
ZKP: tx.ZKP{
|
| 366 |
+
NewStateRoot: common.BytesToHash(inputs.NewStateRoot),
|
| 367 |
+
NewLocalExitRoot: common.BytesToHash(inputs.NewLocalExitRoot),
|
| 368 |
+
Proof: agglayerTypes.ArgBytes(proofBytes),
|
| 369 |
+
},
|
| 370 |
+
RollupID: a.Ethman.GetRollupId(),
|
| 371 |
+
}
|
| 372 |
+
signedTx, err := tx.Sign(a.sequencerPrivateKey)
|
| 373 |
+
|
| 374 |
+
if err != nil {
|
| 375 |
+
log.Errorf("failed to sign tx: %v", err)
|
| 376 |
+
a.handleFailureToSendToAggLayer(ctx, proof)
|
| 377 |
+
|
| 378 |
+
return false
|
| 379 |
+
}
|
| 380 |
+
|
| 381 |
+
log.Debug("final proof signedTx: ", signedTx.Tx.ZKP.Proof.Hex())
|
| 382 |
+
txHash, err := a.AggLayerClient.SendTx(*signedTx)
|
| 383 |
+
if err != nil {
|
| 384 |
+
log.Errorf("failed to send tx to the interop: %v", err)
|
| 385 |
+
a.handleFailureToSendToAggLayer(ctx, proof)
|
| 386 |
+
|
| 387 |
+
return false
|
| 388 |
+
}
|
| 389 |
+
|
| 390 |
+
log.Infof("tx %s sent to agglayer, waiting to be mined", txHash.Hex())
|
| 391 |
+
log.Debugf("Timeout set to %f seconds", a.cfg.AggLayerTxTimeout.Duration.Seconds())
|
| 392 |
+
waitCtx, cancelFunc := context.WithDeadline(ctx, time.Now().Add(a.cfg.AggLayerTxTimeout.Duration))
|
| 393 |
+
defer cancelFunc()
|
| 394 |
+
if err := a.AggLayerClient.WaitTxToBeMined(txHash, waitCtx); err != nil {
|
| 395 |
+
log.Errorf("interop didn't mine the tx: %v", err)
|
| 396 |
+
a.handleFailureToSendToAggLayer(ctx, proof)
|
| 397 |
+
|
| 398 |
+
return false
|
| 399 |
+
}
|
| 400 |
+
|
| 401 |
+
// TODO: wait for synchronizer to catch up
|
| 402 |
+
return true
|
| 403 |
+
}
|
| 404 |
+
|
| 405 |
+
func (a *Aggregator) handleFailureToSendToAggLayer(ctx context.Context, proof *state.Proof) {
|
| 406 |
+
log := log.WithFields("proofId", proof.ProofID, "batches", fmt.Sprintf("%d-%d", proof.BatchNumber, proof.BatchNumberFinal))
|
| 407 |
+
proof.GeneratingSince = nil
|
| 408 |
+
|
| 409 |
+
err := a.State.UpdateGeneratedProof(ctx, proof, nil)
|
| 410 |
+
if err != nil {
|
| 411 |
+
log.Errorf("Failed updating proof state (false): %v", err)
|
| 412 |
+
}
|
| 413 |
+
|
| 414 |
+
a.endProofVerification()
|
| 415 |
+
}
|
| 416 |
+
|
| 417 |
func (a *Aggregator) handleFailureToAddVerifyBatchToBeMonitored(ctx context.Context, proof *state.Proof) {
|
| 418 |
log := log.WithFields("proofId", proof.ProofID, "batches", fmt.Sprintf("%d-%d", proof.BatchNumber, proof.BatchNumberFinal))
|
| 419 |
proof.GeneratingSince = nil
|
|
|
|
| 1138 |
if err != nil {
|
| 1139 |
return nil, err
|
| 1140 |
}
|
| 1141 |
+
leaves, err := a.State.GetLeavesByL1InfoRoot(ctx, *l1InfoRoot, nil)
|
| 1142 |
if err != nil {
|
| 1143 |
return nil, err
|
| 1144 |
}
|
|
@@ -191,7 +191,7 @@
|
|
| 191 |
stateMock := mocks.NewStateMock(t)
|
| 192 |
ethTxManager := mocks.NewEthTxManager(t)
|
| 193 |
etherman := mocks.NewEtherman(t)
|
| 194 |
-
a, err := New(cfg, stateMock, ethTxManager, etherman)
|
| 195 |
require.NoError(err)
|
| 196 |
a.ctx, a.exit = context.WithCancel(context.Background())
|
| 197 |
m := mox{
|
|
@@ -686,7 +686,7 @@
|
|
| 686 |
ethTxManager := mocks.NewEthTxManager(t)
|
| 687 |
etherman := mocks.NewEtherman(t)
|
| 688 |
proverMock := mocks.NewProverMock(t)
|
| 689 |
-
a, err := New(cfg, stateMock, ethTxManager, etherman)
|
| 690 |
require.NoError(err)
|
| 691 |
aggregatorCtx := context.WithValue(context.Background(), "owner", "aggregator") //nolint:staticcheck
|
| 692 |
a.ctx, a.exit = context.WithCancel(aggregatorCtx)
|
|
@@ -801,7 +801,7 @@
|
|
| 801 |
}
|
| 802 |
m.etherman.On("GetLatestBlockHeader", mock.Anything).Return(&types.Header{Number: new(big.Int).SetUint64(1)}, nil).Once()
|
| 803 |
m.stateMock.On("GetVirtualBatch", mock.Anything, lastVerifiedBatchNum+1, nil).Return(&vb, nil).Twice()
|
| 804 |
-
m.stateMock.On("
|
| 805 |
expectedInputProver, err := a.buildInputProver(context.Background(), &batchToProve)
|
| 806 |
require.NoError(err)
|
| 807 |
m.proverMock.On("BatchProof", expectedInputProver).Return(nil, errBanana).Once()
|
|
@@ -844,7 +844,7 @@
|
|
| 844 |
}
|
| 845 |
m.etherman.On("GetLatestBlockHeader", mock.Anything).Return(&types.Header{Number: new(big.Int).SetUint64(1)}, nil).Once()
|
| 846 |
m.stateMock.On("GetVirtualBatch", mock.Anything, lastVerifiedBatchNum+1, nil).Return(&vb, nil).Twice()
|
| 847 |
-
m.stateMock.On("
|
| 848 |
expectedInputProver, err := a.buildInputProver(context.Background(), &batchToProve)
|
| 849 |
require.NoError(err)
|
| 850 |
m.proverMock.On("BatchProof", expectedInputProver).Return(&proofID, nil).Once()
|
|
@@ -888,7 +888,7 @@
|
|
| 888 |
}
|
| 889 |
m.etherman.On("GetLatestBlockHeader", mock.Anything).Return(&types.Header{Number: new(big.Int).SetUint64(1)}, nil).Once()
|
| 890 |
m.stateMock.On("GetVirtualBatch", mock.Anything, lastVerifiedBatchNum+1, nil).Return(&vb, nil).Twice()
|
| 891 |
-
m.stateMock.On("
|
| 892 |
expectedInputProver, err := a.buildInputProver(context.Background(), &batchToProve)
|
| 893 |
require.NoError(err)
|
| 894 |
m.proverMock.On("BatchProof", expectedInputProver).Return(&proofID, nil).Once()
|
|
@@ -932,7 +932,7 @@
|
|
| 932 |
}
|
| 933 |
m.etherman.On("GetLatestBlockHeader", mock.Anything).Return(&types.Header{Number: new(big.Int).SetUint64(1)}, nil).Once()
|
| 934 |
m.stateMock.On("GetVirtualBatch", mock.Anything, lastVerifiedBatchNum+1, nil).Return(&vb, nil).Twice()
|
| 935 |
-
m.stateMock.On("
|
| 936 |
expectedInputProver, err := a.buildInputProver(context.Background(), &batchToProve)
|
| 937 |
require.NoError(err)
|
| 938 |
m.proverMock.On("BatchProof", expectedInputProver).Return(&proofID, nil).Once()
|
|
@@ -989,7 +989,7 @@
|
|
| 989 |
TimestampBatchEtrog: &t,
|
| 990 |
}
|
| 991 |
m.stateMock.On("GetVirtualBatch", mock.Anything, lastVerifiedBatchNum+1, nil).Return(&vb, nil).Twice()
|
| 992 |
-
m.stateMock.On("
|
| 993 |
expectedInputProver, err := a.buildInputProver(context.Background(), &batchToProve)
|
| 994 |
require.NoError(err)
|
| 995 |
m.proverMock.On("BatchProof", expectedInputProver).Return(&proofID, nil).Once()
|
|
@@ -1029,7 +1029,7 @@
|
|
| 1029 |
ethTxManager := mocks.NewEthTxManager(t)
|
| 1030 |
etherman := mocks.NewEtherman(t)
|
| 1031 |
proverMock := mocks.NewProverMock(t)
|
| 1032 |
-
a, err := New(cfg, stateMock, ethTxManager, etherman)
|
| 1033 |
require.NoError(err)
|
| 1034 |
aggregatorCtx := context.WithValue(context.Background(), "owner", "aggregator") //nolint:staticcheck
|
| 1035 |
a.ctx, a.exit = context.WithCancel(aggregatorCtx)
|
|
@@ -1306,7 +1306,7 @@
|
|
| 1306 |
ethTxManager := mocks.NewEthTxManager(t)
|
| 1307 |
etherman := mocks.NewEtherman(t)
|
| 1308 |
proverMock := mocks.NewProverMock(t)
|
| 1309 |
-
a, err := New(cfg, stateMock, ethTxManager, etherman)
|
| 1310 |
require.NoError(err)
|
| 1311 |
aggregatorCtx := context.WithValue(context.Background(), "owner", "aggregator") //nolint:staticcheck
|
| 1312 |
a.ctx, a.exit = context.WithCancel(aggregatorCtx)
|
|
@@ -1436,7 +1436,7 @@
|
|
| 1436 |
ethTxManager := mocks.NewEthTxManager(t)
|
| 1437 |
etherman := mocks.NewEtherman(t)
|
| 1438 |
proverMock := mocks.NewProverMock(t)
|
| 1439 |
-
a, err := New(cfg, stateMock, ethTxManager, etherman)
|
| 1440 |
require.NoError(err)
|
| 1441 |
aggregatorCtx := context.WithValue(context.Background(), "owner", "aggregator") //nolint:staticcheck
|
| 1442 |
a.ctx, a.exit = context.WithCancel(aggregatorCtx)
|
|
|
|
| 191 |
stateMock := mocks.NewStateMock(t)
|
| 192 |
ethTxManager := mocks.NewEthTxManager(t)
|
| 193 |
etherman := mocks.NewEtherman(t)
|
| 194 |
+
a, err := New(cfg, stateMock, ethTxManager, etherman, nil, nil)
|
| 195 |
require.NoError(err)
|
| 196 |
a.ctx, a.exit = context.WithCancel(context.Background())
|
| 197 |
m := mox{
|
|
|
|
| 686 |
ethTxManager := mocks.NewEthTxManager(t)
|
| 687 |
etherman := mocks.NewEtherman(t)
|
| 688 |
proverMock := mocks.NewProverMock(t)
|
| 689 |
+
a, err := New(cfg, stateMock, ethTxManager, etherman, nil, nil)
|
| 690 |
require.NoError(err)
|
| 691 |
aggregatorCtx := context.WithValue(context.Background(), "owner", "aggregator") //nolint:staticcheck
|
| 692 |
a.ctx, a.exit = context.WithCancel(aggregatorCtx)
|
|
|
|
| 801 |
}
|
| 802 |
m.etherman.On("GetLatestBlockHeader", mock.Anything).Return(&types.Header{Number: new(big.Int).SetUint64(1)}, nil).Once()
|
| 803 |
m.stateMock.On("GetVirtualBatch", mock.Anything, lastVerifiedBatchNum+1, nil).Return(&vb, nil).Twice()
|
| 804 |
+
m.stateMock.On("GetLeavesByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice()
|
| 805 |
expectedInputProver, err := a.buildInputProver(context.Background(), &batchToProve)
|
| 806 |
require.NoError(err)
|
| 807 |
m.proverMock.On("BatchProof", expectedInputProver).Return(nil, errBanana).Once()
|
|
|
|
| 844 |
}
|
| 845 |
m.etherman.On("GetLatestBlockHeader", mock.Anything).Return(&types.Header{Number: new(big.Int).SetUint64(1)}, nil).Once()
|
| 846 |
m.stateMock.On("GetVirtualBatch", mock.Anything, lastVerifiedBatchNum+1, nil).Return(&vb, nil).Twice()
|
| 847 |
+
m.stateMock.On("GetLeavesByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice()
|
| 848 |
expectedInputProver, err := a.buildInputProver(context.Background(), &batchToProve)
|
| 849 |
require.NoError(err)
|
| 850 |
m.proverMock.On("BatchProof", expectedInputProver).Return(&proofID, nil).Once()
|
|
|
|
| 888 |
}
|
| 889 |
m.etherman.On("GetLatestBlockHeader", mock.Anything).Return(&types.Header{Number: new(big.Int).SetUint64(1)}, nil).Once()
|
| 890 |
m.stateMock.On("GetVirtualBatch", mock.Anything, lastVerifiedBatchNum+1, nil).Return(&vb, nil).Twice()
|
| 891 |
+
m.stateMock.On("GetLeavesByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice()
|
| 892 |
expectedInputProver, err := a.buildInputProver(context.Background(), &batchToProve)
|
| 893 |
require.NoError(err)
|
| 894 |
m.proverMock.On("BatchProof", expectedInputProver).Return(&proofID, nil).Once()
|
|
|
|
| 932 |
}
|
| 933 |
m.etherman.On("GetLatestBlockHeader", mock.Anything).Return(&types.Header{Number: new(big.Int).SetUint64(1)}, nil).Once()
|
| 934 |
m.stateMock.On("GetVirtualBatch", mock.Anything, lastVerifiedBatchNum+1, nil).Return(&vb, nil).Twice()
|
| 935 |
+
m.stateMock.On("GetLeavesByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice()
|
| 936 |
expectedInputProver, err := a.buildInputProver(context.Background(), &batchToProve)
|
| 937 |
require.NoError(err)
|
| 938 |
m.proverMock.On("BatchProof", expectedInputProver).Return(&proofID, nil).Once()
|
|
|
|
| 989 |
TimestampBatchEtrog: &t,
|
| 990 |
}
|
| 991 |
m.stateMock.On("GetVirtualBatch", mock.Anything, lastVerifiedBatchNum+1, nil).Return(&vb, nil).Twice()
|
| 992 |
+
m.stateMock.On("GetLeavesByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice()
|
| 993 |
expectedInputProver, err := a.buildInputProver(context.Background(), &batchToProve)
|
| 994 |
require.NoError(err)
|
| 995 |
m.proverMock.On("BatchProof", expectedInputProver).Return(&proofID, nil).Once()
|
|
|
|
| 1029 |
ethTxManager := mocks.NewEthTxManager(t)
|
| 1030 |
etherman := mocks.NewEtherman(t)
|
| 1031 |
proverMock := mocks.NewProverMock(t)
|
| 1032 |
+
a, err := New(cfg, stateMock, ethTxManager, etherman, nil, nil)
|
| 1033 |
require.NoError(err)
|
| 1034 |
aggregatorCtx := context.WithValue(context.Background(), "owner", "aggregator") //nolint:staticcheck
|
| 1035 |
a.ctx, a.exit = context.WithCancel(aggregatorCtx)
|
|
|
|
| 1306 |
ethTxManager := mocks.NewEthTxManager(t)
|
| 1307 |
etherman := mocks.NewEtherman(t)
|
| 1308 |
proverMock := mocks.NewProverMock(t)
|
| 1309 |
+
a, err := New(cfg, stateMock, ethTxManager, etherman, nil, nil)
|
| 1310 |
require.NoError(err)
|
| 1311 |
aggregatorCtx := context.WithValue(context.Background(), "owner", "aggregator") //nolint:staticcheck
|
| 1312 |
a.ctx, a.exit = context.WithCancel(aggregatorCtx)
|
|
|
|
| 1436 |
ethTxManager := mocks.NewEthTxManager(t)
|
| 1437 |
etherman := mocks.NewEtherman(t)
|
| 1438 |
proverMock := mocks.NewProverMock(t)
|
| 1439 |
+
a, err := New(cfg, stateMock, ethTxManager, etherman, nil, nil)
|
| 1440 |
require.NoError(err)
|
| 1441 |
aggregatorCtx := context.WithValue(context.Background(), "owner", "aggregator") //nolint:staticcheck
|
| 1442 |
a.ctx, a.exit = context.WithCancel(aggregatorCtx)
|
|
@@ -8,6 +8,17 @@
|
|
| 8 |
"github.com/0xPolygonHermez/zkevm-node/encoding"
|
| 9 |
)
|
| 10 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
// TokenAmountWithDecimals is a wrapper type that parses token amount with decimals to big int
|
| 12 |
type TokenAmountWithDecimals struct {
|
| 13 |
*big.Int `validate:"required"`
|
|
@@ -89,6 +100,18 @@
|
|
| 89 |
// UpgradeEtrogBatchNumber is the number of the first batch after upgrading to etrog
|
| 90 |
UpgradeEtrogBatchNumber uint64 `mapstructure:"UpgradeEtrogBatchNumber"`
|
| 91 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 92 |
// BatchProofL1BlockConfirmations is number of L1 blocks to consider we can generate the proof for a virtual batch
|
| 93 |
BatchProofL1BlockConfirmations uint64 `mapstructure:"BatchProofL1BlockConfirmations"`
|
| 94 |
}
|
|
|
|
| 8 |
"github.com/0xPolygonHermez/zkevm-node/encoding"
|
| 9 |
)
|
| 10 |
|
| 11 |
+
// SettlementBackend is the type of the settlement backend
|
| 12 |
+
type SettlementBackend string
|
| 13 |
+
|
| 14 |
+
const (
|
| 15 |
+
// AggLayer settlement backend
|
| 16 |
+
AggLayer SettlementBackend = "agglayer"
|
| 17 |
+
|
| 18 |
+
// L1 settlement backend
|
| 19 |
+
L1 SettlementBackend = "l1"
|
| 20 |
+
)
|
| 21 |
+
|
| 22 |
// TokenAmountWithDecimals is a wrapper type that parses token amount with decimals to big int
|
| 23 |
type TokenAmountWithDecimals struct {
|
| 24 |
*big.Int `validate:"required"`
|
|
|
|
| 100 |
// UpgradeEtrogBatchNumber is the number of the first batch after upgrading to etrog
|
| 101 |
UpgradeEtrogBatchNumber uint64 `mapstructure:"UpgradeEtrogBatchNumber"`
|
| 102 |
|
| 103 |
+
// SettlementBackend configuration defines how a final ZKP should be settled. Directly to L1 or over the Beethoven service.
|
| 104 |
+
SettlementBackend SettlementBackend `mapstructure:"SettlementBackend"`
|
| 105 |
+
|
| 106 |
+
// AggLayerTxTimeout is the interval time to wait for a tx to be mined from the agglayer
|
| 107 |
+
AggLayerTxTimeout types.Duration `mapstructure:"AggLayerTxTimeout"`
|
| 108 |
+
|
| 109 |
+
// AggLayerURL url of the agglayer service
|
| 110 |
+
AggLayerURL string `mapstructure:"AggLayerURL"`
|
| 111 |
+
|
| 112 |
+
// SequencerPrivateKey Private key of the trusted sequencer
|
| 113 |
+
SequencerPrivateKey types.KeystoreFileConfig `mapstructure:"SequencerPrivateKey"`
|
| 114 |
+
|
| 115 |
// BatchProofL1BlockConfirmations is number of L1 blocks to consider we can generate the proof for a virtual batch
|
| 116 |
BatchProofL1BlockConfirmations uint64 `mapstructure:"BatchProofL1BlockConfirmations"`
|
| 117 |
}
|
|
@@ -38,6 +38,7 @@
|
|
| 38 |
|
| 39 |
// etherman contains the methods required to interact with ethereum
|
| 40 |
type etherman interface {
|
|
|
|
| 41 |
GetLatestVerifiedBatchNum() (uint64, error)
|
| 42 |
BuildTrustedVerifyBatchesTxData(lastVerifiedBatch, newVerifiedBatch uint64, inputs *ethmanTypes.FinalProofInputs, beneficiary common.Address) (to *common.Address, data []byte, err error)
|
| 43 |
GetLatestBlockHeader(ctx context.Context) (*types.Header, error)
|
|
@@ -65,7 +66,7 @@
|
|
| 65 |
CleanupGeneratedProofs(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) error
|
| 66 |
CleanupLockedProofs(ctx context.Context, duration string, dbTx pgx.Tx) (int64, error)
|
| 67 |
GetL1InfoRootLeafByIndex(ctx context.Context, l1InfoTreeIndex uint32, dbTx pgx.Tx) (state.L1InfoTreeExitRootStorageEntry, error)
|
| 68 |
-
|
| 69 |
GetVirtualBatchParentHash(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (common.Hash, error)
|
| 70 |
GetForcedBatchParentHash(ctx context.Context, forcedBatchNumber uint64, dbTx pgx.Tx) (common.Hash, error)
|
| 71 |
GetVirtualBatch(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.VirtualBatch, error)
|
|
|
|
| 38 |
|
| 39 |
// etherman contains the methods required to interact with ethereum
|
| 40 |
type etherman interface {
|
| 41 |
+
GetRollupId() uint32
|
| 42 |
GetLatestVerifiedBatchNum() (uint64, error)
|
| 43 |
BuildTrustedVerifyBatchesTxData(lastVerifiedBatch, newVerifiedBatch uint64, inputs *ethmanTypes.FinalProofInputs, beneficiary common.Address) (to *common.Address, data []byte, err error)
|
| 44 |
GetLatestBlockHeader(ctx context.Context) (*types.Header, error)
|
|
|
|
| 66 |
CleanupGeneratedProofs(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) error
|
| 67 |
CleanupLockedProofs(ctx context.Context, duration string, dbTx pgx.Tx) (int64, error)
|
| 68 |
GetL1InfoRootLeafByIndex(ctx context.Context, l1InfoTreeIndex uint32, dbTx pgx.Tx) (state.L1InfoTreeExitRootStorageEntry, error)
|
| 69 |
+
GetLeavesByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) ([]state.L1InfoTreeExitRootStorageEntry, error)
|
| 70 |
GetVirtualBatchParentHash(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (common.Hash, error)
|
| 71 |
GetForcedBatchParentHash(ctx context.Context, forcedBatchNumber uint64, dbTx pgx.Tx) (common.Hash, error)
|
| 72 |
GetVirtualBatch(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.VirtualBatch, error)
|
|
@@ -51,14 +51,14 @@
|
|
| 51 |
setupLog(c.Log)
|
| 52 |
|
| 53 |
// Check if it is already registered
|
| 54 |
-
etherman, err := newEtherman(*c)
|
| 55 |
if err != nil {
|
| 56 |
log.Fatal(err)
|
| 57 |
return err
|
| 58 |
}
|
| 59 |
|
| 60 |
// load auth from keystore file
|
| 61 |
-
auth, err := etherman.LoadAuthFromKeyStore(addrKeyStorePath, addrPassword)
|
| 62 |
if err != nil {
|
| 63 |
log.Fatal(err)
|
| 64 |
return err
|
|
|
|
| 51 |
setupLog(c.Log)
|
| 52 |
|
| 53 |
// Check if it is already registered
|
| 54 |
+
etherman, err := newEtherman(*c, nil)
|
| 55 |
if err != nil {
|
| 56 |
log.Fatal(err)
|
| 57 |
return err
|
| 58 |
}
|
| 59 |
|
| 60 |
// load auth from keystore file
|
| 61 |
+
auth, _, err := etherman.LoadAuthFromKeyStore(addrKeyStorePath, addrPassword)
|
| 62 |
if err != nil {
|
| 63 |
log.Fatal(err)
|
| 64 |
return err
|
|
@@ -47,7 +47,7 @@
|
|
| 47 |
networkFlag = cli.StringFlag{
|
| 48 |
Name: config.FlagNetwork,
|
| 49 |
Aliases: []string{"net"},
|
| 50 |
-
Usage: "Load default network configuration. Supported values: [`
|
| 51 |
Required: true,
|
| 52 |
}
|
| 53 |
customNetworkFlag = cli.StringFlag{
|
|
@@ -186,6 +186,13 @@
|
|
| 186 |
Action: restore,
|
| 187 |
Flags: restoreFlags,
|
| 188 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 189 |
}
|
| 190 |
|
| 191 |
err := app.Run(os.Args)
|
|
|
|
| 47 |
networkFlag = cli.StringFlag{
|
| 48 |
Name: config.FlagNetwork,
|
| 49 |
Aliases: []string{"net"},
|
| 50 |
+
Usage: "Load default network configuration. Supported values: [`custom`]",
|
| 51 |
Required: true,
|
| 52 |
}
|
| 53 |
customNetworkFlag = cli.StringFlag{
|
|
|
|
| 186 |
Action: restore,
|
| 187 |
Flags: restoreFlags,
|
| 188 |
},
|
| 189 |
+
{
|
| 190 |
+
Name: "set-data-availability-protocol",
|
| 191 |
+
Aliases: []string{"set-dap"},
|
| 192 |
+
Usage: "Sets the new data availability protocol",
|
| 193 |
+
Action: setDataAvailabilityProtocol,
|
| 194 |
+
Flags: setDataAvailabilityProtocolFlags,
|
| 195 |
+
},
|
| 196 |
}
|
| 197 |
|
| 198 |
err := app.Run(os.Args)
|
|
@@ -0,0 +1,308 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package main
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"context"
|
| 5 |
+
"encoding/csv"
|
| 6 |
+
"errors"
|
| 7 |
+
"fmt"
|
| 8 |
+
"os"
|
| 9 |
+
"strings"
|
| 10 |
+
|
| 11 |
+
"github.com/0xPolygonHermez/zkevm-node/config"
|
| 12 |
+
"github.com/0xPolygonHermez/zkevm-node/pool"
|
| 13 |
+
"github.com/0xPolygonHermez/zkevm-node/pool/pgpoolstorage"
|
| 14 |
+
"github.com/ethereum/go-ethereum/common"
|
| 15 |
+
"github.com/urfave/cli/v2"
|
| 16 |
+
)
|
| 17 |
+
|
| 18 |
+
var (
|
| 19 |
+
policyFlag = cli.StringFlag{
|
| 20 |
+
Name: "policy",
|
| 21 |
+
Aliases: []string{"p"},
|
| 22 |
+
Usage: "Name of policy to operate on",
|
| 23 |
+
Required: false,
|
| 24 |
+
}
|
| 25 |
+
csvFlag = cli.StringFlag{
|
| 26 |
+
Name: "csv",
|
| 27 |
+
Usage: "CSV file with addresses",
|
| 28 |
+
Required: false,
|
| 29 |
+
}
|
| 30 |
+
allowFlag = cli.BoolFlag{
|
| 31 |
+
Name: "allow",
|
| 32 |
+
Usage: "Update policy to 'allow' addresses on list",
|
| 33 |
+
Required: false,
|
| 34 |
+
}
|
| 35 |
+
denyFlag = cli.BoolFlag{
|
| 36 |
+
Name: "deny",
|
| 37 |
+
Usage: "Update policy to 'deny' addresses on list",
|
| 38 |
+
Required: false,
|
| 39 |
+
}
|
| 40 |
+
noHeaderFlag = cli.BoolFlag{
|
| 41 |
+
Name: "no-header",
|
| 42 |
+
Value: false,
|
| 43 |
+
Required: false,
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
policyActionFlags = []cli.Flag{&policyFlag}
|
| 47 |
+
)
|
| 48 |
+
|
| 49 |
+
var policyCommands = cli.Command{
|
| 50 |
+
Name: "policy",
|
| 51 |
+
Usage: "View, update, and apply policies",
|
| 52 |
+
Action: describe,
|
| 53 |
+
Flags: []cli.Flag{&configFileFlag},
|
| 54 |
+
Subcommands: []*cli.Command{
|
| 55 |
+
{
|
| 56 |
+
Name: "add",
|
| 57 |
+
Usage: "Add address(es) to a policy exclusion list",
|
| 58 |
+
Action: addAcl,
|
| 59 |
+
Flags: append(policyActionFlags, &csvFlag),
|
| 60 |
+
}, {
|
| 61 |
+
Name: "clear",
|
| 62 |
+
Usage: "Clear the addresses listed as exceptions to a policy",
|
| 63 |
+
Action: clearAcl,
|
| 64 |
+
Flags: policyActionFlags,
|
| 65 |
+
}, {
|
| 66 |
+
Name: "describe",
|
| 67 |
+
Usage: "Describe the default actions for the policies",
|
| 68 |
+
Action: describe,
|
| 69 |
+
Flags: append(policyActionFlags, &noHeaderFlag),
|
| 70 |
+
}, {
|
| 71 |
+
Name: "remove",
|
| 72 |
+
Usage: "Remove address(es) from a policy exclusion list",
|
| 73 |
+
Action: removeAcl,
|
| 74 |
+
Flags: append(policyActionFlags, &csvFlag),
|
| 75 |
+
}, {
|
| 76 |
+
Name: "update",
|
| 77 |
+
Usage: "Update the default action for a policy",
|
| 78 |
+
Action: updatePolicy,
|
| 79 |
+
Flags: append(policyActionFlags, &allowFlag, &denyFlag),
|
| 80 |
+
},
|
| 81 |
+
},
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
func updatePolicy(cli *cli.Context) error {
|
| 85 |
+
_, db, err := configAndStorage(cli)
|
| 86 |
+
if err != nil {
|
| 87 |
+
return err
|
| 88 |
+
}
|
| 89 |
+
policy, err := resolvePolicy(cli)
|
| 90 |
+
if err != nil {
|
| 91 |
+
return err
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
allow := cli.Bool(allowFlag.Name)
|
| 95 |
+
deny := cli.Bool(denyFlag.Name)
|
| 96 |
+
|
| 97 |
+
// exactly one must be set
|
| 98 |
+
if (allow && deny) || (!allow && !deny) {
|
| 99 |
+
return errors.New("supply one policy action [--allow or --deny]")
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
var setting bool
|
| 103 |
+
if allow {
|
| 104 |
+
setting = true
|
| 105 |
+
} else if deny {
|
| 106 |
+
setting = false
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
err = db.UpdatePolicy(context.Background(), policy, setting)
|
| 110 |
+
if err != nil {
|
| 111 |
+
return err
|
| 112 |
+
}
|
| 113 |
+
return nil
|
| 114 |
+
}
|
| 115 |
+
|
| 116 |
+
func addAcl(cli *cli.Context) error {
|
| 117 |
+
_, db, err := configAndStorage(cli)
|
| 118 |
+
if err != nil {
|
| 119 |
+
return err
|
| 120 |
+
}
|
| 121 |
+
policy, addresses, err := requirePolicyAndAddresses(cli)
|
| 122 |
+
if err != nil {
|
| 123 |
+
return err
|
| 124 |
+
}
|
| 125 |
+
err = db.AddAddressesToPolicy(context.Background(), policy, addresses)
|
| 126 |
+
if err != nil {
|
| 127 |
+
return err
|
| 128 |
+
}
|
| 129 |
+
return nil
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
func removeAcl(cli *cli.Context) error {
|
| 133 |
+
_, db, err := configAndStorage(cli)
|
| 134 |
+
if err != nil {
|
| 135 |
+
return err
|
| 136 |
+
}
|
| 137 |
+
policy, addresses, err := requirePolicyAndAddresses(cli)
|
| 138 |
+
if err != nil {
|
| 139 |
+
return err
|
| 140 |
+
}
|
| 141 |
+
err = db.RemoveAddressesFromPolicy(context.Background(), policy, addresses)
|
| 142 |
+
if err != nil {
|
| 143 |
+
return err
|
| 144 |
+
}
|
| 145 |
+
return nil
|
| 146 |
+
}
|
| 147 |
+
|
| 148 |
+
func clearAcl(cli *cli.Context) error {
|
| 149 |
+
_, db, err := configAndStorage(cli)
|
| 150 |
+
if err != nil {
|
| 151 |
+
return err
|
| 152 |
+
}
|
| 153 |
+
policy, err := resolvePolicy(cli)
|
| 154 |
+
if err != nil {
|
| 155 |
+
return err
|
| 156 |
+
}
|
| 157 |
+
err = db.ClearPolicy(context.Background(), policy)
|
| 158 |
+
if err != nil {
|
| 159 |
+
return err
|
| 160 |
+
}
|
| 161 |
+
return nil
|
| 162 |
+
}
|
| 163 |
+
|
| 164 |
+
func describe(cli *cli.Context) error {
|
| 165 |
+
showHeader := !cli.Bool(noHeaderFlag.Name)
|
| 166 |
+
if cli.IsSet(policyFlag.Name) {
|
| 167 |
+
return describePolicy(cli, showHeader)
|
| 168 |
+
}
|
| 169 |
+
return describePolicies(cli, showHeader)
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
func describePolicy(cli *cli.Context, showHeader bool) error {
|
| 173 |
+
_, db, err := configAndStorage(cli)
|
| 174 |
+
if err != nil {
|
| 175 |
+
return err
|
| 176 |
+
}
|
| 177 |
+
|
| 178 |
+
policyName, err := resolvePolicy(cli)
|
| 179 |
+
if err != nil {
|
| 180 |
+
return err
|
| 181 |
+
}
|
| 182 |
+
|
| 183 |
+
if showHeader {
|
| 184 |
+
policy, err := db.DescribePolicy(context.Background(), policyName)
|
| 185 |
+
if err != nil {
|
| 186 |
+
return err
|
| 187 |
+
}
|
| 188 |
+
fmt.Printf("%s: %s\n", "Policy", policy.Name)
|
| 189 |
+
fmt.Printf("%s: %s\n", "Action", policy.Desc())
|
| 190 |
+
}
|
| 191 |
+
query, err := resolveAddresses(cli, false)
|
| 192 |
+
if err != nil {
|
| 193 |
+
return nil
|
| 194 |
+
}
|
| 195 |
+
list, err := db.ListAcl(context.Background(), policyName, query)
|
| 196 |
+
if err != nil {
|
| 197 |
+
return err
|
| 198 |
+
}
|
| 199 |
+
|
| 200 |
+
if showHeader {
|
| 201 |
+
fmt.Println("Addresses:")
|
| 202 |
+
}
|
| 203 |
+
for _, address := range list {
|
| 204 |
+
fmt.Println(address.Hex())
|
| 205 |
+
}
|
| 206 |
+
return nil
|
| 207 |
+
}
|
| 208 |
+
|
| 209 |
+
func describePolicies(cli *cli.Context, showHeader bool) error {
|
| 210 |
+
_, db, err := configAndStorage(cli)
|
| 211 |
+
if err != nil {
|
| 212 |
+
return err
|
| 213 |
+
}
|
| 214 |
+
list, err := db.DescribePolicies(context.Background())
|
| 215 |
+
if err != nil {
|
| 216 |
+
return err
|
| 217 |
+
}
|
| 218 |
+
|
| 219 |
+
if showHeader {
|
| 220 |
+
fmt.Printf("%7s: %s\n", "Policy", "Action")
|
| 221 |
+
}
|
| 222 |
+
for _, p := range list {
|
| 223 |
+
fmt.Printf("%7s: %s\n", p.Name, p.Desc())
|
| 224 |
+
}
|
| 225 |
+
|
| 226 |
+
return nil
|
| 227 |
+
}
|
| 228 |
+
|
| 229 |
+
func configAndStorage(cli *cli.Context) (*config.Config, *pgpoolstorage.PostgresPoolStorage, error) {
|
| 230 |
+
c, err := config.Load(cli, false)
|
| 231 |
+
if err != nil {
|
| 232 |
+
return nil, nil, err
|
| 233 |
+
}
|
| 234 |
+
setupLog(c.Log)
|
| 235 |
+
|
| 236 |
+
db, err := pgpoolstorage.NewPostgresPoolStorage(c.Pool.DB)
|
| 237 |
+
if err != nil {
|
| 238 |
+
return nil, nil, err
|
| 239 |
+
}
|
| 240 |
+
return c, db, nil
|
| 241 |
+
}
|
| 242 |
+
|
| 243 |
+
func requirePolicyAndAddresses(cli *cli.Context) (pool.PolicyName, []common.Address, error) {
|
| 244 |
+
policy, err := resolvePolicy(cli)
|
| 245 |
+
if err != nil {
|
| 246 |
+
return "", nil, err
|
| 247 |
+
}
|
| 248 |
+
addresses, err := resolveAddresses(cli, true)
|
| 249 |
+
if err != nil {
|
| 250 |
+
return "", nil, err
|
| 251 |
+
}
|
| 252 |
+
return policy, addresses, nil
|
| 253 |
+
}
|
| 254 |
+
|
| 255 |
+
func resolvePolicy(cli *cli.Context) (pool.PolicyName, error) {
|
| 256 |
+
policy := cli.String(policyFlag.Name)
|
| 257 |
+
if policy == "" {
|
| 258 |
+
return "", nil
|
| 259 |
+
}
|
| 260 |
+
if !pool.IsPolicy(policy) {
|
| 261 |
+
return "", fmt.Errorf("invalid policy name: %s", policy)
|
| 262 |
+
}
|
| 263 |
+
return pool.PolicyName(policy), nil
|
| 264 |
+
}
|
| 265 |
+
|
| 266 |
+
func resolveAddresses(cli *cli.Context, failIfEmpty bool) ([]common.Address, error) {
|
| 267 |
+
var set = make(map[common.Address]struct{})
|
| 268 |
+
if cli.IsSet("csv") {
|
| 269 |
+
file := cli.String(csvFlag.Name)
|
| 270 |
+
fd, err := os.Open(file)
|
| 271 |
+
if err != nil {
|
| 272 |
+
return nil, err
|
| 273 |
+
}
|
| 274 |
+
defer func(fd *os.File) {
|
| 275 |
+
_ = fd.Close()
|
| 276 |
+
}(fd)
|
| 277 |
+
|
| 278 |
+
fileReader := csv.NewReader(fd)
|
| 279 |
+
records, err := fileReader.ReadAll()
|
| 280 |
+
|
| 281 |
+
if err != nil {
|
| 282 |
+
return nil, err
|
| 283 |
+
}
|
| 284 |
+
for _, row := range records {
|
| 285 |
+
for _, cell := range row {
|
| 286 |
+
hex := strings.TrimSpace(cell)
|
| 287 |
+
set[common.HexToAddress(hex)] = struct{}{}
|
| 288 |
+
}
|
| 289 |
+
}
|
| 290 |
+
}
|
| 291 |
+
|
| 292 |
+
for _, a := range cli.Args().Slice() {
|
| 293 |
+
a = strings.TrimSpace(a)
|
| 294 |
+
a = strings.Trim(a, ",|")
|
| 295 |
+
if !strings.HasPrefix(a, "0x") {
|
| 296 |
+
a = "0x" + a
|
| 297 |
+
}
|
| 298 |
+
set[common.HexToAddress(a)] = struct{}{}
|
| 299 |
+
}
|
| 300 |
+
var ret []common.Address
|
| 301 |
+
for a := range set {
|
| 302 |
+
ret = append(ret, a)
|
| 303 |
+
}
|
| 304 |
+
if failIfEmpty && len(ret) == 0 {
|
| 305 |
+
return nil, errors.New("no addresses given")
|
| 306 |
+
}
|
| 307 |
+
return ret, nil
|
| 308 |
+
}
|
|
@@ -2,6 +2,7 @@
|
|
| 2 |
|
| 3 |
import (
|
| 4 |
"context"
|
|
|
|
| 5 |
"errors"
|
| 6 |
"fmt"
|
| 7 |
"net"
|
|
@@ -37,6 +42,7 @@
|
|
| 37 |
"github.com/0xPolygonHermez/zkevm-node/state/runtime/executor"
|
| 38 |
"github.com/0xPolygonHermez/zkevm-node/synchronizer"
|
| 39 |
"github.com/0xPolygonHermez/zkevm-node/synchronizer/common/syncinterfaces"
|
|
|
|
| 40 |
"github.com/jackc/pgx/v4/pgxpool"
|
| 41 |
"github.com/prometheus/client_golang/prometheus/promhttp"
|
| 42 |
"github.com/urfave/cli/v2"
|
|
@@ -107,19 +113,27 @@
|
|
| 107 |
log.Fatal(err)
|
| 108 |
}
|
| 109 |
|
| 110 |
-
|
|
|
|
| 111 |
if err != nil {
|
| 112 |
log.Fatal(err)
|
| 113 |
}
|
| 114 |
-
|
| 115 |
-
// READ CHAIN ID FROM POE SC
|
| 116 |
-
l2ChainID, err := etherman.GetL2ChainID()
|
| 117 |
if err != nil {
|
| 118 |
log.Fatal(err)
|
| 119 |
}
|
| 120 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 121 |
st, currentForkID := newState(cliCtx.Context, c, etherman, l2ChainID, stateSqlDB, eventLog, needsExecutor, needsStateTree, false)
|
| 122 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 123 |
c.Aggregator.ChainID = l2ChainID
|
| 124 |
c.Sequencer.StreamServer.ChainID = l2ChainID
|
| 125 |
log.Infof("Chain ID read from POE SC = %v", l2ChainID)
|
|
@@ -276,8 +290,88 @@
|
|
| 276 |
}
|
| 277 |
}
|
| 278 |
|
| 279 |
-
func newEtherman(c config.Config) (*etherman.Client, error) {
|
| 280 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 281 |
}
|
| 282 |
|
| 283 |
func runSynchronizer(cfg config.Config, etherman *etherman.Client, ethTxManagerStorage *ethtxmanager.PostgresStorage, st *state.State, pool *pool.Pool, eventLog *event.EventLog) {
|
|
@@ -295,12 +389,23 @@
|
|
| 295 |
}
|
| 296 |
log.Info("trustedSequencerURL ", trustedSequencerURL)
|
| 297 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 298 |
zkEVMClient := client.NewClient(trustedSequencerURL)
|
| 299 |
etherManForL1 := []syncinterfaces.EthermanFullInterface{}
|
| 300 |
// If synchronizer are using sequential mode, we only need one etherman client
|
| 301 |
if cfg.Synchronizer.L1SynchronizationMode == synchronizer.ParallelMode {
|
| 302 |
for i := 0; i < int(cfg.Synchronizer.L1ParallelSynchronization.MaxClients+1); i++ {
|
| 303 |
-
eth, err := newEtherman(cfg)
|
| 304 |
if err != nil {
|
| 305 |
log.Fatal(err)
|
| 306 |
}
|
|
@@ -310,7 +415,7 @@
|
|
| 310 |
etm := ethtxmanager.New(cfg.EthTxManager, etherman, ethTxManagerStorage, st)
|
| 311 |
sy, err := synchronizer.NewSynchronizer(
|
| 312 |
cfg.IsTrustedSequencer, etherman, etherManForL1, st, pool, etm,
|
| 313 |
-
zkEVMClient, eventLog, cfg.NetworkConfig.Genesis, cfg.Synchronizer, cfg.Log.Environment == "development",
|
| 314 |
)
|
| 315 |
if err != nil {
|
| 316 |
log.Fatal(err)
|
|
@@ -403,12 +508,12 @@
|
|
| 403 |
}
|
| 404 |
|
| 405 |
func createSequenceSender(cfg config.Config, pool *pool.Pool, etmStorage *ethtxmanager.PostgresStorage, st *state.State, eventLog *event.EventLog) *sequencesender.SequenceSender {
|
| 406 |
-
etherman, err := newEtherman(cfg)
|
| 407 |
if err != nil {
|
| 408 |
log.Fatal(err)
|
| 409 |
}
|
| 410 |
|
| 411 |
-
auth, err := etherman.LoadAuthFromKeyStore(cfg.SequenceSender.PrivateKey.Path, cfg.SequenceSender.PrivateKey.Password)
|
| 412 |
if err != nil {
|
| 413 |
log.Fatal(err)
|
| 414 |
}
|
|
@@ -418,7 +523,12 @@
|
|
| 418 |
|
| 419 |
ethTxManager := ethtxmanager.New(cfg.EthTxManager, etherman, etmStorage, st)
|
| 420 |
|
| 421 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 422 |
if err != nil {
|
| 423 |
log.Fatal(err)
|
| 424 |
}
|
|
@@ -427,7 +537,23 @@
|
|
| 427 |
}
|
| 428 |
|
| 429 |
func runAggregator(ctx context.Context, c aggregator.Config, etherman *etherman.Client, ethTxManager *ethtxmanager.Client, st *state.State) {
|
| 430 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 431 |
if err != nil {
|
| 432 |
log.Fatal(err)
|
| 433 |
}
|
|
@@ -497,14 +623,14 @@
|
|
| 497 |
}
|
| 498 |
log.Infof("Starting L1InfoRoot: %v", l1inforoot.String())
|
| 499 |
|
| 500 |
-
forkIDIntervals, err := forkIDIntervals(ctx, st, etherman, c.NetworkConfig.Genesis.
|
| 501 |
if err != nil {
|
| 502 |
log.Fatal("error getting forkIDs. Error: ", err)
|
| 503 |
}
|
| 504 |
st.UpdateForkIDIntervalsInMemory(forkIDIntervals)
|
| 505 |
|
| 506 |
currentForkID := forkIDIntervals[len(forkIDIntervals)-1].ForkId
|
| 507 |
-
log.Infof("Fork ID read from POE SC = %v",
|
| 508 |
|
| 509 |
return st, currentForkID
|
| 510 |
}
|
|
@@ -520,13 +646,13 @@
|
|
| 520 |
}
|
| 521 |
|
| 522 |
func createEthTxManager(cfg config.Config, etmStorage *ethtxmanager.PostgresStorage, st *state.State) *ethtxmanager.Client {
|
| 523 |
-
etherman, err := newEtherman(cfg)
|
| 524 |
if err != nil {
|
| 525 |
log.Fatal(err)
|
| 526 |
}
|
| 527 |
|
| 528 |
for _, privateKey := range cfg.EthTxManager.PrivateKeys {
|
| 529 |
-
_, err := etherman.LoadAuthFromKeyStore(privateKey.Path, privateKey.Password)
|
| 530 |
if err != nil {
|
| 531 |
log.Fatal(err)
|
| 532 |
}
|
|
@@ -658,14 +784,32 @@
|
|
| 658 |
}
|
| 659 |
forkIDIntervals = forkIntervals
|
| 660 |
} else {
|
| 661 |
-
log.Debug("Getting
|
| 662 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 663 |
if err != nil {
|
| 664 |
return []state.ForkIDInterval{}, fmt.Errorf("error getting forks. Please check the configuration. Error: %v", err)
|
| 665 |
} else if len(forkIntervals) == 0 {
|
| 666 |
return []state.ForkIDInterval{}, fmt.Errorf("error: no forkID received. It should receive at least one, please check the configuration...")
|
| 667 |
}
|
| 668 |
forkIDIntervals = forkIntervals
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 669 |
}
|
| 670 |
}
|
| 671 |
return forkIDIntervals, nil
|
|
|
|
| 2 |
|
| 3 |
import (
|
| 4 |
"context"
|
| 5 |
+
"crypto/ecdsa"
|
| 6 |
"errors"
|
| 7 |
"fmt"
|
| 8 |
"net"
|
|
|
|
| 42 |
"github.com/0xPolygonHermez/zkevm-node/state/runtime/executor"
|
| 43 |
"github.com/0xPolygonHermez/zkevm-node/synchronizer"
|
| 44 |
"github.com/0xPolygonHermez/zkevm-node/synchronizer/common/syncinterfaces"
|
| 45 |
+
"github.com/ethereum/go-ethereum/ethclient"
|
| 46 |
"github.com/jackc/pgx/v4/pgxpool"
|
| 47 |
"github.com/prometheus/client_golang/prometheus/promhttp"
|
| 48 |
"github.com/urfave/cli/v2"
|
|
|
|
| 113 |
log.Fatal(err)
|
| 114 |
}
|
| 115 |
|
| 116 |
+
// READ CHAIN ID FROM POE SC
|
| 117 |
+
tmpEthMan, err := etherman.NewClient(c.Etherman, c.NetworkConfig.L1Config, nil, nil)
|
| 118 |
if err != nil {
|
| 119 |
log.Fatal(err)
|
| 120 |
}
|
| 121 |
+
l2ChainID, err := tmpEthMan.GetL2ChainID()
|
|
|
|
|
|
|
| 122 |
if err != nil {
|
| 123 |
log.Fatal(err)
|
| 124 |
}
|
| 125 |
|
| 126 |
+
etherman, err := etherman.NewClient(c.Etherman, c.NetworkConfig.L1Config, nil, nil)
|
| 127 |
+
if err != nil {
|
| 128 |
+
log.Fatal(err)
|
| 129 |
+
}
|
| 130 |
st, currentForkID := newState(cliCtx.Context, c, etherman, l2ChainID, stateSqlDB, eventLog, needsExecutor, needsStateTree, false)
|
| 131 |
|
| 132 |
+
etherman, err = newEtherman(*c, st)
|
| 133 |
+
if err != nil {
|
| 134 |
+
log.Fatal(err)
|
| 135 |
+
}
|
| 136 |
+
|
| 137 |
c.Aggregator.ChainID = l2ChainID
|
| 138 |
c.Sequencer.StreamServer.ChainID = l2ChainID
|
| 139 |
log.Infof("Chain ID read from POE SC = %v", l2ChainID)
|
|
|
|
| 290 |
}
|
| 291 |
}
|
| 292 |
|
| 293 |
+
func newEtherman(c config.Config, st *state.State) (*etherman.Client, error) {
|
| 294 |
+
ethman, err := etherman.NewClient(c.Etherman, c.NetworkConfig.L1Config, nil, nil)
|
| 295 |
+
if err != nil {
|
| 296 |
+
return nil, err
|
| 297 |
+
}
|
| 298 |
+
da, err := newDataAvailability(c, st, ethman, false)
|
| 299 |
+
if err != nil {
|
| 300 |
+
return nil, err
|
| 301 |
+
}
|
| 302 |
+
return etherman.NewClient(c.Etherman, c.NetworkConfig.L1Config, da, st)
|
| 303 |
+
}
|
| 304 |
+
|
| 305 |
+
func newDataAvailability(c config.Config, st *state.State, etherman *etherman.Client, isSequenceSender bool) (*dataavailability.DataAvailability, error) {
|
| 306 |
+
var (
|
| 307 |
+
trustedSequencerURL string
|
| 308 |
+
err error
|
| 309 |
+
)
|
| 310 |
+
if !c.IsTrustedSequencer {
|
| 311 |
+
if c.Synchronizer.TrustedSequencerURL != "" {
|
| 312 |
+
trustedSequencerURL = c.Synchronizer.TrustedSequencerURL
|
| 313 |
+
} else {
|
| 314 |
+
log.Debug("getting trusted sequencer URL from smc")
|
| 315 |
+
trustedSequencerURL, err = etherman.GetTrustedSequencerURL()
|
| 316 |
+
if err != nil {
|
| 317 |
+
return nil, fmt.Errorf("error getting trusted sequencer URI. Error: %v", err)
|
| 318 |
+
}
|
| 319 |
+
}
|
| 320 |
+
log.Debug("trustedSequencerURL ", trustedSequencerURL)
|
| 321 |
+
}
|
| 322 |
+
zkEVMClient := client.NewClient(trustedSequencerURL)
|
| 323 |
+
|
| 324 |
+
// Backend specific config
|
| 325 |
+
daProtocolName, err := etherman.GetDAProtocolName()
|
| 326 |
+
if err != nil {
|
| 327 |
+
return nil, fmt.Errorf("error getting data availability protocol name: %v", err)
|
| 328 |
+
}
|
| 329 |
+
var daBackend dataavailability.DABackender
|
| 330 |
+
switch daProtocolName {
|
| 331 |
+
case string(dataavailability.DataAvailabilityCommittee):
|
| 332 |
+
var (
|
| 333 |
+
pk *ecdsa.PrivateKey
|
| 334 |
+
err error
|
| 335 |
+
)
|
| 336 |
+
if isSequenceSender {
|
| 337 |
+
_, pk, err = etherman.LoadAuthFromKeyStore(c.SequenceSender.PrivateKey.Path, c.SequenceSender.PrivateKey.Password)
|
| 338 |
+
if err != nil {
|
| 339 |
+
return nil, err
|
| 340 |
+
}
|
| 341 |
+
}
|
| 342 |
+
dacAddr, err := etherman.GetDAProtocolAddr()
|
| 343 |
+
if err != nil {
|
| 344 |
+
return nil, fmt.Errorf("error getting trusted sequencer URI. Error: %v", err)
|
| 345 |
+
}
|
| 346 |
+
|
| 347 |
+
daBackend, err = datacommittee.New(
|
| 348 |
+
c.Etherman.URL,
|
| 349 |
+
dacAddr,
|
| 350 |
+
pk,
|
| 351 |
+
dataCommitteeClient.NewFactory(),
|
| 352 |
+
)
|
| 353 |
+
if err != nil {
|
| 354 |
+
return nil, err
|
| 355 |
+
}
|
| 356 |
+
default:
|
| 357 |
+
return nil, fmt.Errorf("unexpected / unsupported DA protocol: %s", daProtocolName)
|
| 358 |
+
}
|
| 359 |
+
|
| 360 |
+
return dataavailability.New(
|
| 361 |
+
c.IsTrustedSequencer,
|
| 362 |
+
daBackend,
|
| 363 |
+
st,
|
| 364 |
+
zkEVMClient,
|
| 365 |
+
)
|
| 366 |
+
}
|
| 367 |
+
|
| 368 |
+
func newL2EthClient(url string) (*ethclient.Client, error) {
|
| 369 |
+
ethClient, err := ethclient.Dial(url)
|
| 370 |
+
if err != nil {
|
| 371 |
+
log.Errorf("error connecting L1 to %s: %+v", url, err)
|
| 372 |
+
return nil, err
|
| 373 |
+
}
|
| 374 |
+
return ethClient, nil
|
| 375 |
}
|
| 376 |
|
| 377 |
func runSynchronizer(cfg config.Config, etherman *etherman.Client, ethTxManagerStorage *ethtxmanager.PostgresStorage, st *state.State, pool *pool.Pool, eventLog *event.EventLog) {
|
|
|
|
| 389 |
}
|
| 390 |
log.Info("trustedSequencerURL ", trustedSequencerURL)
|
| 391 |
}
|
| 392 |
+
var ethClientForL2 *ethclient.Client
|
| 393 |
+
if trustedSequencerURL != "" {
|
| 394 |
+
log.Infof("Creating L2 ethereum client %s", trustedSequencerURL)
|
| 395 |
+
ethClientForL2, err = newL2EthClient(trustedSequencerURL)
|
| 396 |
+
if err != nil {
|
| 397 |
+
log.Fatalf("Can't create L2 ethereum client. Err:%w", err)
|
| 398 |
+
}
|
| 399 |
+
} else {
|
| 400 |
+
ethClientForL2 = nil
|
| 401 |
+
log.Infof("skipping creating L2 ethereum client because URL is empty")
|
| 402 |
+
}
|
| 403 |
zkEVMClient := client.NewClient(trustedSequencerURL)
|
| 404 |
etherManForL1 := []syncinterfaces.EthermanFullInterface{}
|
| 405 |
// If synchronizer are using sequential mode, we only need one etherman client
|
| 406 |
if cfg.Synchronizer.L1SynchronizationMode == synchronizer.ParallelMode {
|
| 407 |
for i := 0; i < int(cfg.Synchronizer.L1ParallelSynchronization.MaxClients+1); i++ {
|
| 408 |
+
eth, err := newEtherman(cfg, st)
|
| 409 |
if err != nil {
|
| 410 |
log.Fatal(err)
|
| 411 |
}
|
|
|
|
| 415 |
etm := ethtxmanager.New(cfg.EthTxManager, etherman, ethTxManagerStorage, st)
|
| 416 |
sy, err := synchronizer.NewSynchronizer(
|
| 417 |
cfg.IsTrustedSequencer, etherman, etherManForL1, st, pool, etm,
|
| 418 |
+
zkEVMClient, ethClientForL2, eventLog, cfg.NetworkConfig.Genesis, cfg.Synchronizer, cfg.Log.Environment == "development",
|
| 419 |
)
|
| 420 |
if err != nil {
|
| 421 |
log.Fatal(err)
|
|
|
|
| 508 |
}
|
| 509 |
|
| 510 |
func createSequenceSender(cfg config.Config, pool *pool.Pool, etmStorage *ethtxmanager.PostgresStorage, st *state.State, eventLog *event.EventLog) *sequencesender.SequenceSender {
|
| 511 |
+
etherman, err := newEtherman(cfg, st)
|
| 512 |
if err != nil {
|
| 513 |
log.Fatal(err)
|
| 514 |
}
|
| 515 |
|
| 516 |
+
auth, _, err := etherman.LoadAuthFromKeyStore(cfg.SequenceSender.PrivateKey.Path, cfg.SequenceSender.PrivateKey.Password)
|
| 517 |
if err != nil {
|
| 518 |
log.Fatal(err)
|
| 519 |
}
|
|
|
|
| 523 |
|
| 524 |
ethTxManager := ethtxmanager.New(cfg.EthTxManager, etherman, etmStorage, st)
|
| 525 |
|
| 526 |
+
da, err := newDataAvailability(cfg, st, etherman, true)
|
| 527 |
+
if err != nil {
|
| 528 |
+
log.Fatal(err)
|
| 529 |
+
}
|
| 530 |
+
|
| 531 |
+
seqSender, err := sequencesender.New(cfg.SequenceSender, st, etherman, ethTxManager, eventLog, da)
|
| 532 |
if err != nil {
|
| 533 |
log.Fatal(err)
|
| 534 |
}
|
|
|
|
| 537 |
}
|
| 538 |
|
| 539 |
func runAggregator(ctx context.Context, c aggregator.Config, etherman *etherman.Client, ethTxManager *ethtxmanager.Client, st *state.State) {
|
| 540 |
+
var (
|
| 541 |
+
aggCli *agglayerClient.Client
|
| 542 |
+
pk *ecdsa.PrivateKey
|
| 543 |
+
err error
|
| 544 |
+
)
|
| 545 |
+
|
| 546 |
+
if c.SettlementBackend == aggregator.AggLayer {
|
| 547 |
+
aggCli = agglayerClient.New(c.AggLayerURL)
|
| 548 |
+
|
| 549 |
+
// Load private key
|
| 550 |
+
pk, err = config.NewKeyFromKeystore(c.SequencerPrivateKey)
|
| 551 |
+
if err != nil {
|
| 552 |
+
log.Fatal(err)
|
| 553 |
+
}
|
| 554 |
+
}
|
| 555 |
+
|
| 556 |
+
agg, err := aggregator.New(c, st, ethTxManager, etherman, aggCli, pk)
|
| 557 |
if err != nil {
|
| 558 |
log.Fatal(err)
|
| 559 |
}
|
|
|
|
| 623 |
}
|
| 624 |
log.Infof("Starting L1InfoRoot: %v", l1inforoot.String())
|
| 625 |
|
| 626 |
+
forkIDIntervals, err := forkIDIntervals(ctx, st, etherman, c.NetworkConfig.Genesis.RollupBlockNumber)
|
| 627 |
if err != nil {
|
| 628 |
log.Fatal("error getting forkIDs. Error: ", err)
|
| 629 |
}
|
| 630 |
st.UpdateForkIDIntervalsInMemory(forkIDIntervals)
|
| 631 |
|
| 632 |
currentForkID := forkIDIntervals[len(forkIDIntervals)-1].ForkId
|
| 633 |
+
log.Infof("Fork ID read from POE SC = %v", currentForkID)
|
| 634 |
|
| 635 |
return st, currentForkID
|
| 636 |
}
|
|
|
|
| 646 |
}
|
| 647 |
|
| 648 |
func createEthTxManager(cfg config.Config, etmStorage *ethtxmanager.PostgresStorage, st *state.State) *ethtxmanager.Client {
|
| 649 |
+
etherman, err := newEtherman(cfg, st)
|
| 650 |
if err != nil {
|
| 651 |
log.Fatal(err)
|
| 652 |
}
|
| 653 |
|
| 654 |
for _, privateKey := range cfg.EthTxManager.PrivateKeys {
|
| 655 |
+
_, _, err := etherman.LoadAuthFromKeyStore(privateKey.Path, privateKey.Password)
|
| 656 |
if err != nil {
|
| 657 |
log.Fatal(err)
|
| 658 |
}
|
|
|
|
| 784 |
}
|
| 785 |
forkIDIntervals = forkIntervals
|
| 786 |
} else {
|
| 787 |
+
log.Debug("Getting all forkIDs")
|
| 788 |
+
|
| 789 |
+
// Get last L1 block number
|
| 790 |
+
bn, err := etherman.GetLatestBlockNumber(ctx)
|
| 791 |
+
if err != nil {
|
| 792 |
+
return []state.ForkIDInterval{}, fmt.Errorf("error getting latest block number. Error: %v", err)
|
| 793 |
+
}
|
| 794 |
+
|
| 795 |
+
// Get all forkIDs since genesis
|
| 796 |
+
forkIntervals, err := etherman.GetForks(ctx, genesisBlockNumber, bn)
|
| 797 |
if err != nil {
|
| 798 |
return []state.ForkIDInterval{}, fmt.Errorf("error getting forks. Please check the configuration. Error: %v", err)
|
| 799 |
} else if len(forkIntervals) == 0 {
|
| 800 |
return []state.ForkIDInterval{}, fmt.Errorf("error: no forkID received. It should receive at least one, please check the configuration...")
|
| 801 |
}
|
| 802 |
forkIDIntervals = forkIntervals
|
| 803 |
+
|
| 804 |
+
log.Debugf("Retrieved %d forkIDs", len(forkIDIntervals))
|
| 805 |
+
|
| 806 |
+
log.Debug("Adding forkIDs to db and memory")
|
| 807 |
+
for _, forkID := range forkIDIntervals {
|
| 808 |
+
err = st.AddForkIDInterval(ctx, forkID, nil)
|
| 809 |
+
if err != nil {
|
| 810 |
+
log.Fatal("error adding forkID to db. Error: ", err)
|
| 811 |
+
}
|
| 812 |
+
}
|
| 813 |
}
|
| 814 |
}
|
| 815 |
return forkIDIntervals, nil
|
|
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package main
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"github.com/0xPolygonHermez/zkevm-node/config"
|
| 5 |
+
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 6 |
+
"github.com/ethereum/go-ethereum/common"
|
| 7 |
+
"github.com/urfave/cli/v2"
|
| 8 |
+
)
|
| 9 |
+
|
| 10 |
+
const flagDAAddress = "data-availability-address"
|
| 11 |
+
|
| 12 |
+
var setDataAvailabilityProtocolFlags = []cli.Flag{
|
| 13 |
+
&cli.StringFlag{
|
| 14 |
+
Name: flagDAAddress,
|
| 15 |
+
Aliases: []string{"da-addr"},
|
| 16 |
+
Usage: "address of the new data availibility protocol",
|
| 17 |
+
Required: true,
|
| 18 |
+
},
|
| 19 |
+
&cli.StringFlag{
|
| 20 |
+
Name: config.FlagKeyStorePath,
|
| 21 |
+
Aliases: []string{"ksp"},
|
| 22 |
+
Usage: "the path of the key store file containing the private key of the account going to set new data availability protocol",
|
| 23 |
+
Required: true,
|
| 24 |
+
},
|
| 25 |
+
&cli.StringFlag{
|
| 26 |
+
Name: config.FlagPassword,
|
| 27 |
+
Aliases: []string{"pw"},
|
| 28 |
+
Usage: "the password do decrypt the key store file",
|
| 29 |
+
Required: true,
|
| 30 |
+
},
|
| 31 |
+
&configFileFlag,
|
| 32 |
+
&networkFlag,
|
| 33 |
+
&customNetworkFlag,
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
func setDataAvailabilityProtocol(ctx *cli.Context) error {
|
| 37 |
+
c, err := config.Load(ctx, true)
|
| 38 |
+
if err != nil {
|
| 39 |
+
return err
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
setupLog(c.Log)
|
| 43 |
+
|
| 44 |
+
daAddress := common.HexToAddress(ctx.String(flagDAAddress))
|
| 45 |
+
addrKeyStorePath := ctx.String(config.FlagKeyStorePath)
|
| 46 |
+
addrPassword := ctx.String(config.FlagPassword)
|
| 47 |
+
|
| 48 |
+
etherman, err := newEtherman(*c, nil)
|
| 49 |
+
if err != nil {
|
| 50 |
+
log.Fatal(err)
|
| 51 |
+
return err
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
auth, _, err := etherman.LoadAuthFromKeyStore(addrKeyStorePath, addrPassword)
|
| 55 |
+
if err != nil {
|
| 56 |
+
log.Fatal(err)
|
| 57 |
+
return err
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
tx, err := etherman.SetDataAvailabilityProtocol(auth.From, daAddress)
|
| 61 |
+
if err != nil {
|
| 62 |
+
return err
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
log.Infof("Transaction to set new data availability protocol sent. Hash: %s", tx.Hash())
|
| 66 |
+
|
| 67 |
+
return nil
|
| 68 |
+
}
|
|
@@ -1,109 +0,0 @@
|
|
| 1 |
-
package config
|
| 2 |
-
|
| 3 |
-
// CardonaNetworkConfigJSON is the hardcoded network configuration to be used for the official mainnet setup
|
| 4 |
-
const CardonaNetworkConfigJSON = `
|
| 5 |
-
{
|
| 6 |
-
"l1Config": {
|
| 7 |
-
"polygonZkEVMAddress": "0xA13Ddb14437A8F34897131367ad3ca78416d6bCa",
|
| 8 |
-
"polygonZkEVMBridgeAddress": "0x528e26b25a34a4A5d0dbDa1d57D318153d2ED582",
|
| 9 |
-
"polygonZkEVMGlobalExitRootAddress": "0xAd1490c248c5d3CbAE399Fd529b79B42984277DF",
|
| 10 |
-
"polTokenAddress": "0x6a7c3F4B0651d6DA389AD1d11D962ea458cDCA70",
|
| 11 |
-
"polygonRollupManagerAddress": "0x32d33D5137a7cFFb54c5Bf8371172bcEc5f310ff",
|
| 12 |
-
"chainId": 11155111
|
| 13 |
-
},
|
| 14 |
-
"genesisBlockNumber": 4789190,
|
| 15 |
-
"root": "0x91dfcdeb628dfdc51f3a2ee38cb17c78581e4e7ff91bcc2e327d24a9dfa46982",
|
| 16 |
-
"genesis": [
|
| 17 |
-
{
|
| 18 |
-
"contractName": "PolygonZkEVMDeployer",
|
| 19 |
-
"balance": "0",
|
| 20 |
-
"nonce": "4",
|
| 21 |
-
"address": "0x36810012486fc134D0679c07f85fe5ba5A087D8C",
|
| 22 |
-
"bytecode": "0x6080604052600436106100705760003560e01c8063715018a61161004e578063715018a6146100e65780638da5cb5b146100fb578063e11ae6cb14610126578063f2fde38b1461013957600080fd5b80632b79805a146100755780634a94d4871461008a5780636d07dbf81461009d575b600080fd5b610088610083366004610927565b610159565b005b6100886100983660046109c7565b6101cb565b3480156100a957600080fd5b506100bd6100b8366004610a1e565b61020d565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b50610088610220565b34801561010757600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166100bd565b610088610134366004610a40565b610234565b34801561014557600080fd5b50610088610154366004610a90565b61029b565b610161610357565b600061016e8585856103d8565b905061017a8183610537565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527fba82f25fed02cd2a23d9f5d11c2ef588d22af5437cbf23bfe61d87257c480e4c9060200160405180910390a15050505050565b6101d3610357565b6101de83838361057b565b506040517f25adb19089b6a549831a273acdf7908cff8b7ee5f551f8d1d37996cf01c5df5b90600090a1505050565b600061021983836105a9565b9392505050565b610228610357565b61023260006105b6565b565b61023c610357565b60006102498484846103d8565b60405173ffffffffffffffffffffffffffffffffffffffff821681529091507fba82f25fed02cd2a23d9f5d11c2ef588d22af5437cbf23bfe61d87257c480e4c9060200160405180910390a150505050565b6102a3610357565b73ffffffffffffffffffffffffffffffffffffffff811661034b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610354816105b6565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610232576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610342565b600083471015610444576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e63650000006044820152606401610342565b81516000036104af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f6044820152606401610342565b8282516020840186f5905073ffffffffffffffffffffffffffffffffffffffff8116610219576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f79000000000000006044820152606401610342565b6060610219838360006040518060400160405280601e81526020017f416464726573733a206c6f772d6c6576656c2063616c6c206661696c6564000081525061062b565b60606105a1848484604051806060016040528060298152602001610b3d6029913961062b565b949350505050565b6000610219838330610744565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060824710156106bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610342565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516106e69190610acf565b60006040518083038185875af1925050503d8060008114610723576040519150601f19603f3d011682016040523d82523d6000602084013e610728565b606091505b50915091506107398783838761076e565b979650505050505050565b6000604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b606083156108045782516000036107fd5773ffffffffffffffffffffffffffffffffffffffff85163b6107fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610342565b50816105a1565b6105a183838151156108195781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103429190610aeb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261088d57600080fd5b813567ffffffffffffffff808211156108a8576108a861084d565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156108ee576108ee61084d565b8160405283815286602085880101111561090757600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000806080858703121561093d57600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561096357600080fd5b61096f8883890161087c565b9350606087013591508082111561098557600080fd5b506109928782880161087c565b91505092959194509250565b803573ffffffffffffffffffffffffffffffffffffffff811681146109c257600080fd5b919050565b6000806000606084860312156109dc57600080fd5b6109e58461099e565b9250602084013567ffffffffffffffff811115610a0157600080fd5b610a0d8682870161087c565b925050604084013590509250925092565b60008060408385031215610a3157600080fd5b50508035926020909101359150565b600080600060608486031215610a5557600080fd5b8335925060208401359150604084013567ffffffffffffffff811115610a7a57600080fd5b610a868682870161087c565b9150509250925092565b600060208284031215610aa257600080fd5b6102198261099e565b60005b83811015610ac6578181015183820152602001610aae565b50506000910152565b60008251610ae1818460208701610aab565b9190910192915050565b6020815260008251806020840152610b0a816040850160208701610aab565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2063616c6c20776974682076616c7565206661696c6564a26469706673582212203e70ce334e8ec9d8d03e87415afd36dce4e82633bd277b08937095a6bd66367764736f6c63430008110033",
|
| 23 |
-
"storage": {
|
| 24 |
-
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000ff6250d0e86a2465b0c1bf8e36409503d6a26963"
|
| 25 |
-
}
|
| 26 |
-
},
|
| 27 |
-
{
|
| 28 |
-
"contractName": "ProxyAdmin",
|
| 29 |
-
"balance": "0",
|
| 30 |
-
"nonce": "1",
|
| 31 |
-
"address": "0x85cEB41028B1a5ED2b88E395145344837308b251",
|
| 32 |
-
"bytecode": "0x60806040526004361061007b5760003560e01c80639623609d1161004e5780639623609d1461012b57806399a88ec41461013e578063f2fde38b1461015e578063f3b7dead1461017e57600080fd5b8063204e1c7a14610080578063715018a6146100c95780637eff275e146100e05780638da5cb5b14610100575b600080fd5b34801561008c57600080fd5b506100a061009b366004610608565b61019e565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100d557600080fd5b506100de610255565b005b3480156100ec57600080fd5b506100de6100fb36600461062c565b610269565b34801561010c57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166100a0565b6100de610139366004610694565b6102f7565b34801561014a57600080fd5b506100de61015936600461062c565b61038c565b34801561016a57600080fd5b506100de610179366004610608565b6103e8565b34801561018a57600080fd5b506100a0610199366004610608565b6104a4565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907f5c60da1b00000000000000000000000000000000000000000000000000000000815260040190565b600060405180830381855afa9150503d8060008114610225576040519150601f19603f3d011682016040523d82523d6000602084013e61022a565b606091505b50915091508161023957600080fd5b8080602001905181019061024d9190610788565b949350505050565b61025d6104f0565b6102676000610571565b565b6102716104f0565b6040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690638f283970906024015b600060405180830381600087803b1580156102db57600080fd5b505af11580156102ef573d6000803e3d6000fd5b505050505050565b6102ff6104f0565b6040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690634f1ef28690349061035590869086906004016107a5565b6000604051808303818588803b15801561036e57600080fd5b505af1158015610382573d6000803e3d6000fd5b5050505050505050565b6103946104f0565b6040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690633659cfe6906024016102c1565b6103f06104f0565b73ffffffffffffffffffffffffffffffffffffffff8116610498576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6104a181610571565b50565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907ff851a44000000000000000000000000000000000000000000000000000000000815260040190565b60005473ffffffffffffffffffffffffffffffffffffffff163314610267576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161048f565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff811681146104a157600080fd5b60006020828403121561061a57600080fd5b8135610625816105e6565b9392505050565b6000806040838503121561063f57600080fd5b823561064a816105e6565b9150602083013561065a816105e6565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000606084860312156106a957600080fd5b83356106b4816105e6565b925060208401356106c4816105e6565b9150604084013567ffffffffffffffff808211156106e157600080fd5b818601915086601f8301126106f557600080fd5b81358181111561070757610707610665565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561074d5761074d610665565b8160405282815289602084870101111561076657600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b60006020828403121561079a57600080fd5b8151610625816105e6565b73ffffffffffffffffffffffffffffffffffffffff8316815260006020604081840152835180604085015260005b818110156107ef578581018301518582016060015282016107d3565b5060006060828601015260607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010192505050939250505056fea2646970667358221220372a0e10eebea1b7fa43ae4c976994e6ed01d85eedc3637b83f01d3f06be442064736f6c63430008110033",
|
| 33 |
-
"storage": {
|
| 34 |
-
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000dbc6981a11fc2b000c635bfa7c47676b25c87d39"
|
| 35 |
-
}
|
| 36 |
-
},
|
| 37 |
-
{
|
| 38 |
-
"contractName": "PolygonZkEVMBridge implementation",
|
| 39 |
-
"balance": "0",
|
| 40 |
-
"nonce": "1",
|
| 41 |
-
"address": "0x8BD36ca1A55e389335004872aA3C3Be0969D3aA7",
|
| 42 |
-
"bytecode": "0x6080604052600436106200019f5760003560e01c8063647c576c11620000e7578063be5831c71162000089578063dbc169761162000060578063dbc169761462000639578063ee25560b1462000651578063fb570834146200068257600080fd5b8063be5831c714620005ae578063cd58657914620005ea578063d02103ca146200060157600080fd5b80639e34070f11620000be5780639e34070f146200050a578063aaa13cc2146200054f578063bab161bf146200057457600080fd5b8063647c576c146200048657806379e2cf9714620004ab57806381b1c17414620004c357600080fd5b80632d2c9d94116200015157806334ac9cf2116200012857806334ac9cf2146200034b5780633ae05047146200037a5780633e197043146200039257600080fd5b80632d2c9d9414620002765780632dfdf0b5146200029b578063318aee3d14620002c257600080fd5b806322e95f2c116200018657806322e95f2c14620001ef578063240ff378146200023a5780632cffd02e146200025157600080fd5b806315064c9614620001a45780632072f6c514620001d5575b600080fd5b348015620001b157600080fd5b50606854620001c09060ff1681565b60405190151581526020015b60405180910390f35b348015620001e257600080fd5b50620001ed620006a7565b005b348015620001fc57600080fd5b50620002146200020e366004620032db565b62000705565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620001cc565b620001ed6200024b36600462003372565b620007a8565b3480156200025e57600080fd5b50620001ed6200027036600462003409565b620009d0565b3480156200028357600080fd5b50620001ed6200029536600462003409565b62000f74565b348015620002a857600080fd5b50620002b360535481565b604051908152602001620001cc565b348015620002cf57600080fd5b5062000319620002e1366004620034ef565b606b6020526000908152604090205463ffffffff811690640100000000900473ffffffffffffffffffffffffffffffffffffffff1682565b6040805163ffffffff909316835273ffffffffffffffffffffffffffffffffffffffff909116602083015201620001cc565b3480156200035857600080fd5b50606c54620002149073ffffffffffffffffffffffffffffffffffffffff1681565b3480156200038757600080fd5b50620002b362001178565b3480156200039f57600080fd5b50620002b3620003b136600462003526565b6040517fff0000000000000000000000000000000000000000000000000000000000000060f889901b1660208201527fffffffff0000000000000000000000000000000000000000000000000000000060e088811b821660218401527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606089811b821660258601529188901b909216603984015285901b16603d8201526051810183905260718101829052600090609101604051602081830303815290604052805190602001209050979650505050505050565b3480156200049357600080fd5b50620001ed620004a5366004620035b0565b6200125e565b348015620004b857600080fd5b50620001ed620014ad565b348015620004d057600080fd5b5062000214620004e236600462003600565b606a6020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b3480156200051757600080fd5b50620001c06200052936600462003600565b600881901c600090815260696020526040902054600160ff9092169190911b9081161490565b3480156200055c57600080fd5b50620002146200056e3660046200361a565b620014e7565b3480156200058157600080fd5b506068546200059890610100900463ffffffff1681565b60405163ffffffff9091168152602001620001cc565b348015620005bb57600080fd5b506068546200059890790100000000000000000000000000000000000000000000000000900463ffffffff1681565b620001ed620005fb366004620036ce565b620016d3565b3480156200060e57600080fd5b50606854620002149065010000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156200064657600080fd5b50620001ed62001c37565b3480156200065e57600080fd5b50620002b36200067036600462003600565b60696020526000908152604090205481565b3480156200068f57600080fd5b50620001c0620006a136600462003770565b62001c93565b606c5473ffffffffffffffffffffffffffffffffffffffff163314620006f9576040517fe2e8106b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6200070362001d7c565b565b6040805160e084901b7fffffffff0000000000000000000000000000000000000000000000000000000016602080830191909152606084901b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602483015282516018818403018152603890920183528151918101919091206000908152606a909152205473ffffffffffffffffffffffffffffffffffffffff165b92915050565b60685460ff1615620007e6576040517f2f0047fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60685463ffffffff8681166101009092041614806200080c5750600263ffffffff861610155b1562000844576040517f0595ea2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b6001606860019054906101000a900463ffffffff163388883488886053546040516200089a9998979695949392919062003806565b60405180910390a1620009b8620009b26001606860019054906101000a900463ffffffff16338989348989604051620008d592919062003881565b60405180910390206040517fff0000000000000000000000000000000000000000000000000000000000000060f889901b1660208201527fffffffff0000000000000000000000000000000000000000000000000000000060e088811b821660218401527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606089811b821660258601529188901b909216603984015285901b16603d8201526051810183905260718101829052600090609101604051602081830303815290604052805190602001209050979650505050505050565b62001e10565b8215620009c957620009c962001f27565b5050505050565b60685460ff161562000a0e576040517f2f0047fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62000a258b8b8b8b8b8b8b8b8b8b8b600062001ffc565b73ffffffffffffffffffffffffffffffffffffffff861662000b01576040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff861690859060405162000a7a9190620038e6565b60006040518083038185875af1925050503d806000811462000ab9576040519150601f19603f3d011682016040523d82523d6000602084013e62000abe565b606091505b505090508062000afa576040517f6747a28800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5062000efc565b60685463ffffffff61010090910481169088160362000b435762000b3d73ffffffffffffffffffffffffffffffffffffffff87168585620021ed565b62000efc565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e089901b1660208201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b166024820152600090603801604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152606a90935291205490915073ffffffffffffffffffffffffffffffffffffffff168062000e6e576000808062000c1886880188620039fb565b92509250925060008584848460405162000c329062003292565b62000c409392919062003abd565b8190604051809103906000f590508015801562000c61573d6000803e3d6000fd5b506040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8c81166004830152602482018c9052919250908216906340c10f1990604401600060405180830381600087803b15801562000cd757600080fd5b505af115801562000cec573d6000803e3d6000fd5b5050505080606a600088815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060405180604001604052808e63ffffffff1681526020018d73ffffffffffffffffffffffffffffffffffffffff16815250606b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050507f490e59a1701b938786ac72570a1efeac994a3dbe96e2e883e19e902ace6e6a398d8d838b8b60405162000e5c95949392919062003afa565b60405180910390a15050505062000ef9565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8781166004830152602482018790528216906340c10f1990604401600060405180830381600087803b15801562000edf57600080fd5b505af115801562000ef4573d6000803e3d6000fd5b505050505b50505b6040805163ffffffff8c811682528916602082015273ffffffffffffffffffffffffffffffffffffffff88811682840152861660608201526080810185905290517f25308c93ceeed162da955b3f7ce3e3f93606579e40fb92029faa9efe275459839181900360a00190a15050505050505050505050565b60685460ff161562000fb2576040517f2f0047fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62000fc98b8b8b8b8b8b8b8b8b8b8b600162001ffc565b60008473ffffffffffffffffffffffffffffffffffffffff1684888a868660405160240162000ffc949392919062003b42565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1806b5f200000000000000000000000000000000000000000000000000000000179052516200107f9190620038e6565b60006040518083038185875af1925050503d8060008114620010be576040519150601f19603f3d011682016040523d82523d6000602084013e620010c3565b606091505b5050905080620010ff576040517f37e391c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805163ffffffff8d811682528a16602082015273ffffffffffffffffffffffffffffffffffffffff89811682840152871660608201526080810186905290517f25308c93ceeed162da955b3f7ce3e3f93606579e40fb92029faa9efe275459839181900360a00190a1505050505050505050505050565b605354600090819081805b602081101562001255578083901c600116600103620011e65760338160208110620011b257620011b262003b8a565b0154604080516020810192909252810185905260600160405160208183030381529060405280519060200120935062001213565b60408051602081018690529081018390526060016040516020818303038152906040528051906020012093505b604080516020810184905290810183905260600160405160208183030381529060405280519060200120915080806200124c9062003be8565b91505062001183565b50919392505050565b600054610100900460ff16158080156200127f5750600054600160ff909116105b806200129b5750303b1580156200129b575060005460ff166001145b6200132d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156200138c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b606880547fffffffffffffff000000000000000000000000000000000000000000000000ff1661010063ffffffff8716027fffffffffffffff0000000000000000000000000000000000000000ffffffffff16176501000000000073ffffffffffffffffffffffffffffffffffffffff8681169190910291909117909155606c80547fffffffffffffffffffffffff00000000000000000000000000000000000000001691841691909117905562001443620022c3565b8015620014a757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b605354606854790100000000000000000000000000000000000000000000000000900463ffffffff16101562000703576200070362001f27565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e089901b1660208201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b1660248201526000908190603801604051602081830303815290604052805190602001209050600060ff60f81b3083604051806020016200157d9062003292565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f909101166040819052620015c8908d908d908d908d908d9060200162003c23565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905262001606929160200162003c64565b604051602081830303815290604052805190602001206040516020016200168f94939291907fff0000000000000000000000000000000000000000000000000000000000000094909416845260609290921b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660018401526015830152603582015260550190565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101209a9950505050505050505050565b60685460ff161562001711576040517f2f0047fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6200171b62002366565b60685463ffffffff888116610100909204161480620017415750600263ffffffff881610155b1562001779576040517f0595ea2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060608773ffffffffffffffffffffffffffffffffffffffff8816620017df57883414620017d5576040517fb89240f500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000925062001ad9565b341562001818576040517f798ee6f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8089166000908152606b602090815260409182902082518084019093525463ffffffff811683526401000000009004909216918101829052901562001908576040517f9dc29fac000000000000000000000000000000000000000000000000000000008152336004820152602481018b905273ffffffffffffffffffffffffffffffffffffffff8a1690639dc29fac90604401600060405180830381600087803b158015620018db57600080fd5b505af1158015620018f0573d6000803e3d6000fd5b50505050806020015194508060000151935062001ad7565b85156200191d576200191d898b8989620023db565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8b16906370a0823190602401602060405180830381865afa1580156200198b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620019b1919062003c97565b9050620019d773ffffffffffffffffffffffffffffffffffffffff8b1633308e620028f9565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8c16906370a0823190602401602060405180830381865afa15801562001a45573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001a6b919062003c97565b905062001a79828262003cb1565b6068548c9850610100900463ffffffff169650935062001a998762002959565b62001aa48c62002a71565b62001aaf8d62002b7e565b60405160200162001ac39392919062003abd565b604051602081830303815290604052945050505b505b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b600084868e8e868860535460405162001b1b98979695949392919062003cc7565b60405180910390a162001c0f620009b2600085878f8f8789805190602001206040517fff0000000000000000000000000000000000000000000000000000000000000060f889901b1660208201527fffffffff0000000000000000000000000000000000000000000000000000000060e088811b821660218401527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606089811b821660258601529188901b909216603984015285901b16603d8201526051810183905260718101829052600090609101604051602081830303815290604052805190602001209050979650505050505050565b861562001c205762001c2062001f27565b5050505062001c2e60018055565b50505050505050565b606c5473ffffffffffffffffffffffffffffffffffffffff16331462001c89576040517fe2e8106b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6200070362002c80565b600084815b602081101562001d6e57600163ffffffff8616821c8116900362001d0a5785816020811062001ccb5762001ccb62003b8a565b60200201358260405160200162001cec929190918252602082015260400190565b60405160208183030381529060405280519060200120915062001d59565b8186826020811062001d205762001d2062003b8a565b602002013560405160200162001d40929190918252602082015260400190565b6040516020818303038152906040528051906020012091505b8062001d658162003be8565b91505062001c98565b50821490505b949350505050565b60685460ff161562001dba576040517f2f0047fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040517f2261efe5aef6fedc1fd1550b25facc9181745623049c7901287030b9ad1a549790600090a1565b80600162001e216020600262003e79565b62001e2d919062003cb1565b6053541062001e68576040517fef5ccf6600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060536000815462001e7b9062003be8565b9182905550905060005b602081101562001f17578082901c60011660010362001ebd57826033826020811062001eb55762001eb562003b8a565b015550505050565b6033816020811062001ed35762001ed362003b8a565b01546040805160208101929092528101849052606001604051602081830303815290604052805190602001209250808062001f0e9062003be8565b91505062001e85565b5062001f2262003e87565b505050565b6053546068805463ffffffff909216790100000000000000000000000000000000000000000000000000027fffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffffff909216919091179081905573ffffffffffffffffffffffffffffffffffffffff65010000000000909104166333d6247d62001fad62001178565b6040518263ffffffff1660e01b815260040162001fcc91815260200190565b600060405180830381600087803b15801562001fe757600080fd5b505af1158015620014a7573d6000803e3d6000fd5b6200200d8b63ffffffff1662002d10565b6068546040805160208082018e90528183018d9052825180830384018152606083019384905280519101207f257b363200000000000000000000000000000000000000000000000000000000909252606481019190915260009165010000000000900473ffffffffffffffffffffffffffffffffffffffff169063257b3632906084016020604051808303816000875af1158015620020b0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620020d6919062003c97565b90508060000362002112576040517e2f6fad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60685463ffffffff88811661010090920416146200215c576040517f0595ea2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606854600090610100900463ffffffff166200217a5750896200217d565b508a5b620021a66200219d848c8c8c8c8c8c8c604051620008d592919062003881565b8f8f8462001c93565b620021dd576040517fe0417cec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905262001f229084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915262002d75565b600054610100900460ff166200235c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162001324565b6200070362002e88565b600260015403620023d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640162001324565b6002600155565b6000620023ec600482848662003eb6565b620023f79162003ee2565b90507f2afa5331000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000821601620026765760008080808080806200245a896004818d62003eb6565b81019062002469919062003f2b565b96509650965096509650965096503373ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614620024dd576040517f912ecce700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff861630146200252d576040517f750643af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8a851462002567576040517f03fffc4b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805173ffffffffffffffffffffffffffffffffffffffff89811660248301528881166044830152606482018890526084820187905260ff861660a483015260c4820185905260e48083018590528351808403909101815261010490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd505accf000000000000000000000000000000000000000000000000000000001790529151918e1691620026229190620038e6565b6000604051808303816000865af19150503d806000811462002661576040519150601f19603f3d011682016040523d82523d6000602084013e62002666565b606091505b50505050505050505050620009c9565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f8fcbaf0c0000000000000000000000000000000000000000000000000000000014620026f2576040517fe282c0ba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808080808080806200270a8a6004818e62003eb6565b81019062002719919062003f86565b975097509750975097509750975097503373ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff16146200278f576040517f912ecce700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87163014620027df576040517f750643af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805173ffffffffffffffffffffffffffffffffffffffff8a811660248301528981166044830152606482018990526084820188905286151560a483015260ff861660c483015260e482018590526101048083018590528351808403909101815261012490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f8fcbaf0c000000000000000000000000000000000000000000000000000000001790529151918f1691620028a39190620038e6565b6000604051808303816000865af19150503d8060008114620028e2576040519150601f19603f3d011682016040523d82523d6000602084013e620028e7565b606091505b50505050505050505050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052620014a79085907f23b872dd000000000000000000000000000000000000000000000000000000009060840162002240565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f06fdde03000000000000000000000000000000000000000000000000000000001790529051606091600091829173ffffffffffffffffffffffffffffffffffffffff861691620029dd9190620038e6565b600060405180830381855afa9150503d806000811462002a1a576040519150601f19603f3d011682016040523d82523d6000602084013e62002a1f565b606091505b50915091508162002a66576040518060400160405280600781526020017f4e4f5f4e414d450000000000000000000000000000000000000000000000000081525062001d74565b62001d748162002f21565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f95d89b41000000000000000000000000000000000000000000000000000000001790529051606091600091829173ffffffffffffffffffffffffffffffffffffffff86169162002af59190620038e6565b600060405180830381855afa9150503d806000811462002b32576040519150601f19603f3d011682016040523d82523d6000602084013e62002b37565b606091505b50915091508162002a66576040518060400160405280600981526020017f4e4f5f53594d424f4c000000000000000000000000000000000000000000000081525062001d74565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f313ce5670000000000000000000000000000000000000000000000000000000017905290516000918291829173ffffffffffffffffffffffffffffffffffffffff86169162002c019190620038e6565b600060405180830381855afa9150503d806000811462002c3e576040519150601f19603f3d011682016040523d82523d6000602084013e62002c43565b606091505b509150915081801562002c57575080516020145b62002c6457601262001d74565b8080602001905181019062001d74919062004012565b60018055565b60685460ff1662002cbd576040517f5386698100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040517f1e5e34eea33501aecf2ebec9fe0e884a40804275ea7fe10b2ba084c8374308b390600090a1565b600881901c60008181526069602052604081208054600160ff861690811b91821892839055929091908183169003620009c9576040517f646cf55800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600062002dd9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16620031119092919063ffffffff16565b80519091501562001f22578080602001905181019062002dfa919062004032565b62001f22576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840162001324565b600054610100900460ff1662002c7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162001324565b6060604082511062002f435781806020019051810190620007a2919062004052565b8151602003620030d35760005b60208110801562002f9b575082818151811062002f715762002f7162003b8a565b01602001517fff000000000000000000000000000000000000000000000000000000000000001615155b1562002fb6578062002fad8162003be8565b91505062002f50565b8060000362002ffa57505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e4700000000000000000000000000006020820152919050565b60008167ffffffffffffffff81111562003018576200301862003891565b6040519080825280601f01601f19166020018201604052801562003043576020820181803683370190505b50905060005b82811015620030cb5784818151811062003067576200306762003b8a565b602001015160f81c60f81b82828151811062003087576200308762003b8a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535080620030c28162003be8565b91505062003049565b509392505050565b505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e470000000000000000000000000000602082015290565b919050565b606062001d748484600085856000808673ffffffffffffffffffffffffffffffffffffffff168587604051620031489190620038e6565b60006040518083038185875af1925050503d806000811462003187576040519150601f19603f3d011682016040523d82523d6000602084013e6200318c565b606091505b50915091506200319f87838387620031aa565b979650505050505050565b60608315620032455782516000036200323d5773ffffffffffffffffffffffffffffffffffffffff85163b6200323d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162001324565b508162001d74565b62001d7483838151156200325c5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620013249190620040d2565b611b6680620040e883390190565b803563ffffffff811681146200310c57600080fd5b73ffffffffffffffffffffffffffffffffffffffff81168114620032d857600080fd5b50565b60008060408385031215620032ef57600080fd5b620032fa83620032a0565b915060208301356200330c81620032b5565b809150509250929050565b8015158114620032d857600080fd5b60008083601f8401126200333957600080fd5b50813567ffffffffffffffff8111156200335257600080fd5b6020830191508360208285010111156200336b57600080fd5b9250929050565b6000806000806000608086880312156200338b57600080fd5b6200339686620032a0565b94506020860135620033a881620032b5565b93506040860135620033ba8162003317565b9250606086013567ffffffffffffffff811115620033d757600080fd5b620033e58882890162003326565b969995985093965092949392505050565b806104008101831015620007a257600080fd5b60008060008060008060008060008060006105208c8e0312156200342c57600080fd5b620034388d8d620033f6565b9a50620034496104008d01620032a0565b99506104208c013598506104408c013597506200346a6104608d01620032a0565b96506104808c01356200347d81620032b5565b95506200348e6104a08d01620032a0565b94506104c08c0135620034a181620032b5565b93506104e08c013592506105008c013567ffffffffffffffff811115620034c757600080fd5b620034d58e828f0162003326565b915080935050809150509295989b509295989b9093969950565b6000602082840312156200350257600080fd5b81356200350f81620032b5565b9392505050565b60ff81168114620032d857600080fd5b600080600080600080600060e0888a0312156200354257600080fd5b87356200354f8162003516565b96506200355f60208901620032a0565b955060408801356200357181620032b5565b94506200358160608901620032a0565b935060808801356200359381620032b5565b9699959850939692959460a0840135945060c09093013592915050565b600080600060608486031215620035c657600080fd5b620035d184620032a0565b92506020840135620035e381620032b5565b91506040840135620035f581620032b5565b809150509250925092565b6000602082840312156200361357600080fd5b5035919050565b600080600080600080600060a0888a0312156200363657600080fd5b6200364188620032a0565b965060208801356200365381620032b5565b9550604088013567ffffffffffffffff808211156200367157600080fd5b6200367f8b838c0162003326565b909750955060608a01359150808211156200369957600080fd5b50620036a88a828b0162003326565b9094509250506080880135620036be8162003516565b8091505092959891949750929550565b600080600080600080600060c0888a031215620036ea57600080fd5b620036f588620032a0565b965060208801356200370781620032b5565b95506040880135945060608801356200372081620032b5565b93506080880135620037328162003317565b925060a088013567ffffffffffffffff8111156200374f57600080fd5b6200375d8a828b0162003326565b989b979a50959850939692959293505050565b60008060008061046085870312156200378857600080fd5b843593506200379b8660208701620033f6565b9250620037ac6104208601620032a0565b939692955092936104400135925050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b600061010060ff8c16835263ffffffff808c16602085015273ffffffffffffffffffffffffffffffffffffffff808c166040860152818b166060860152808a166080860152508760a08501528160c0850152620038678285018789620037bd565b925080851660e085015250509a9950505050505050505050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60005b83811015620038dd578181015183820152602001620038c3565b50506000910152565b60008251620038fa818460208701620038c0565b9190910192915050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156200394e576200394e62003891565b604052919050565b600067ffffffffffffffff82111562003973576200397362003891565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112620039b157600080fd5b8135620039c8620039c28262003956565b62003904565b818152846020838601011115620039de57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060006060848603121562003a1157600080fd5b833567ffffffffffffffff8082111562003a2a57600080fd5b62003a38878388016200399f565b9450602086013591508082111562003a4f57600080fd5b5062003a5e868287016200399f565b9250506040840135620035f58162003516565b6000815180845262003a8b816020860160208601620038c0565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60608152600062003ad2606083018662003a71565b828103602084015262003ae6818662003a71565b91505060ff83166040830152949350505050565b63ffffffff86168152600073ffffffffffffffffffffffffffffffffffffffff8087166020840152808616604084015250608060608301526200319f608083018486620037bd565b73ffffffffffffffffffffffffffffffffffffffff8516815263ffffffff8416602082015260606040820152600062003b80606083018486620037bd565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820362003c1c5762003c1c62003bb9565b5060010190565b60608152600062003c39606083018789620037bd565b828103602084015262003c4e818688620037bd565b91505060ff831660408301529695505050505050565b6000835162003c78818460208801620038c0565b83519083019062003c8e818360208801620038c0565b01949350505050565b60006020828403121562003caa57600080fd5b5051919050565b81810381811115620007a257620007a262003bb9565b600061010060ff8b16835263ffffffff808b16602085015273ffffffffffffffffffffffffffffffffffffffff808b166040860152818a1660608601528089166080860152508660a08501528160c085015262003d278285018762003a71565b925080851660e085015250509998505050505050505050565b600181815b8085111562003d9f57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111562003d835762003d8362003bb9565b8085161562003d9157918102915b93841c939080029062003d45565b509250929050565b60008262003db857506001620007a2565b8162003dc757506000620007a2565b816001811462003de0576002811462003deb5762003e0b565b6001915050620007a2565b60ff84111562003dff5762003dff62003bb9565b50506001821b620007a2565b5060208310610133831016604e8410600b841016171562003e30575081810a620007a2565b62003e3c838362003d40565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111562003e715762003e7162003bb9565b029392505050565b60006200350f838362003da7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b6000808585111562003ec757600080fd5b8386111562003ed557600080fd5b5050820193919092039150565b7fffffffff00000000000000000000000000000000000000000000000000000000813581811691600485101562003f235780818660040360031b1b83161692505b505092915050565b600080600080600080600060e0888a03121562003f4757600080fd5b873562003f5481620032b5565b9650602088013562003f6681620032b5565b955060408801359450606088013593506080880135620035938162003516565b600080600080600080600080610100898b03121562003fa457600080fd5b883562003fb181620032b5565b9750602089013562003fc381620032b5565b96506040890135955060608901359450608089013562003fe38162003317565b935060a089013562003ff58162003516565b979a969950949793969295929450505060c08201359160e0013590565b6000602082840312156200402557600080fd5b81516200350f8162003516565b6000602082840312156200404557600080fd5b81516200350f8162003317565b6000602082840312156200406557600080fd5b815167ffffffffffffffff8111156200407d57600080fd5b8201601f810184136200408f57600080fd5b8051620040a0620039c28262003956565b818152856020838501011115620040b657600080fd5b620040c9826020830160208601620038c0565b95945050505050565b6020815260006200350f602083018462003a7156fe6101006040523480156200001257600080fd5b5060405162001b6638038062001b6683398101604081905262000035916200028d565b82826003620000458382620003a1565b506004620000548282620003a1565b50503360c0525060ff811660e052466080819052620000739062000080565b60a052506200046d915050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f620000ad6200012e565b805160209182012060408051808201825260018152603160f81b90840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b6060600380546200013f9062000312565b80601f01602080910402602001604051908101604052809291908181526020018280546200016d9062000312565b8015620001be5780601f106200019257610100808354040283529160200191620001be565b820191906000526020600020905b815481529060010190602001808311620001a057829003601f168201915b5050505050905090565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001f057600080fd5b81516001600160401b03808211156200020d576200020d620001c8565b604051601f8301601f19908116603f01168101908282118183101715620002385762000238620001c8565b816040528381526020925086838588010111156200025557600080fd5b600091505b838210156200027957858201830151818301840152908201906200025a565b600093810190920192909252949350505050565b600080600060608486031215620002a357600080fd5b83516001600160401b0380821115620002bb57600080fd5b620002c987838801620001de565b94506020860151915080821115620002e057600080fd5b50620002ef86828701620001de565b925050604084015160ff811681146200030757600080fd5b809150509250925092565b600181811c908216806200032757607f821691505b6020821081036200034857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200039c57600081815260208120601f850160051c81016020861015620003775750805b601f850160051c820191505b81811015620003985782815560010162000383565b5050505b505050565b81516001600160401b03811115620003bd57620003bd620001c8565b620003d581620003ce845462000312565b846200034e565b602080601f8311600181146200040d5760008415620003f45750858301515b600019600386901b1c1916600185901b17855562000398565b600085815260208120601f198616915b828110156200043e578886015182559484019460019091019084016200041d565b50858210156200045d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e0516116aa620004bc6000396000610237015260008181610307015281816105c001526106a70152600061053a015260008181610379015261050401526116aa6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063a457c2d71161008c578063d505accf11610066578063d505accf1461039b578063dd62ed3e146103ae578063ffa1ad74146103f457600080fd5b8063a457c2d71461034e578063a9059cbb14610361578063cd0d00961461037457600080fd5b806395d89b41116100bd57806395d89b41146102e75780639dc29fac146102ef578063a3c573eb1461030257600080fd5b806370a08231146102915780637ecebe00146102c757600080fd5b806330adf81f1161012f5780633644e515116101145780633644e51514610261578063395093511461026957806340c10f191461027c57600080fd5b806330adf81f14610209578063313ce5671461023057600080fd5b806318160ddd1161016057806318160ddd146101bd57806320606b70146101cf57806323b872dd146101f657600080fd5b806306fdde031461017c578063095ea7b31461019a575b600080fd5b610184610430565b60405161019191906113e4565b60405180910390f35b6101ad6101a8366004611479565b6104c2565b6040519015158152602001610191565b6002545b604051908152602001610191565b6101c17f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b6101ad6102043660046114a3565b6104dc565b6101c17f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610191565b6101c1610500565b6101ad610277366004611479565b61055c565b61028f61028a366004611479565b6105a8565b005b6101c161029f3660046114df565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101c16102d53660046114df565b60056020526000908152604090205481565b610184610680565b61028f6102fd366004611479565b61068f565b6103297f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610191565b6101ad61035c366004611479565b61075e565b6101ad61036f366004611479565b61082f565b6101c17f000000000000000000000000000000000000000000000000000000000000000081565b61028f6103a9366004611501565b61083d565b6101c16103bc366004611574565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101846040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525081565b60606003805461043f906115a7565b80601f016020809104026020016040519081016040528092919081815260200182805461046b906115a7565b80156104b85780601f1061048d576101008083540402835291602001916104b8565b820191906000526020600020905b81548152906001019060200180831161049b57829003601f168201915b5050505050905090565b6000336104d0818585610b73565b60019150505b92915050565b6000336104ea858285610d27565b6104f5858585610dfe565b506001949350505050565b60007f00000000000000000000000000000000000000000000000000000000000000004614610537576105324661106d565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906104d090829086906105a3908790611629565b610b73565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60448201527f6c79676f6e5a6b45564d4272696467650000000000000000000000000000000060648201526084015b60405180910390fd5b61067c8282611135565b5050565b60606004805461043f906115a7565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610754576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60448201527f6c79676f6e5a6b45564d427269646765000000000000000000000000000000006064820152608401610669565b61067c8282611228565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610822576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610669565b6104f58286868403610b73565b6000336104d0818585610dfe565b834211156108cc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f546f6b656e577261707065643a3a7065726d69743a204578706972656420706560448201527f726d6974000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260056020526040812080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918a918a918a9190866109268361163c565b9091555060408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610991610500565b6040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281019190915260428101839052606201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600080855291840180845281905260ff89169284019290925260608301879052608083018690529092509060019060a0016020604051602081039080840390855afa158015610a55573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811615801590610ad057508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b610b5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f546f6b656e577261707065643a3a7065726d69743a20496e76616c696420736960448201527f676e6174757265000000000000000000000000000000000000000000000000006064820152608401610669565b610b678a8a8a610b73565b50505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8216610cb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610df85781811015610deb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610669565b610df88484848403610b73565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610ea1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8216610f44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610ffa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610df8565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f611098610430565b8051602091820120604080518082018252600181527f310000000000000000000000000000000000000000000000000000000000000090840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b73ffffffffffffffffffffffffffffffffffffffff82166111b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610669565b80600260008282546111c49190611629565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff82166112cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015611381576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610d1a565b600060208083528351808285015260005b81811015611411578581018301518582016040015282016113f5565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461147457600080fd5b919050565b6000806040838503121561148c57600080fd5b61149583611450565b946020939093013593505050565b6000806000606084860312156114b857600080fd5b6114c184611450565b92506114cf60208501611450565b9150604084013590509250925092565b6000602082840312156114f157600080fd5b6114fa82611450565b9392505050565b600080600080600080600060e0888a03121561151c57600080fd5b61152588611450565b965061153360208901611450565b95506040880135945060608801359350608088013560ff8116811461155757600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561158757600080fd5b61159083611450565b915061159e60208401611450565b90509250929050565b600181811c908216806115bb57607f821691505b6020821081036115f4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156104d6576104d66115fa565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361166d5761166d6115fa565b506001019056fea26469706673582212208d88fee561cff7120d381c345cfc534cef8229a272dc5809d4bbb685ad67141164736f6c63430008110033a2646970667358221220d9b3ca7b13ec80ac58634ddf0ecebe71e209a71f532614949b9e720413f50c8364736f6c63430008110033"
|
| 43 |
-
},
|
| 44 |
-
{
|
| 45 |
-
"contractName": "PolygonZkEVMBridge proxy",
|
| 46 |
-
"balance": "200000000000000000000000000",
|
| 47 |
-
"nonce": "1",
|
| 48 |
-
"address": "0x528e26b25a34a4A5d0dbDa1d57D318153d2ED582",
|
| 49 |
-
"bytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461088b565b610135565b61006b6100a33660046108a6565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461088b565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109bb602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b600061022161052a565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b61042283610552565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a16101748161059f565b60606000808573ffffffffffffffffffffffffffffffffffffffff16856040516104cf919061094d565b600060405180830381855af49150503d806000811461050a576040519150601f19603f3d011682016040523d82523d6000602084013e61050f565b606091505b5091509150610520868383876106ab565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b61055b81610753565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff8116610642576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561074157825160000361073a5773ffffffffffffffffffffffffffffffffffffffff85163b61073a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016103a2565b508161074b565b61074b838361081e565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff81163b6107f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610665565b81511561082e5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610969565b803573ffffffffffffffffffffffffffffffffffffffff8116811461088657600080fd5b919050565b60006020828403121561089d57600080fd5b6102b182610862565b6000806000604084860312156108bb57600080fd5b6108c484610862565b9250602084013567ffffffffffffffff808211156108e157600080fd5b818601915086601f8301126108f557600080fd5b81358181111561090457600080fd5b87602082850101111561091657600080fd5b6020830194508093505050509250925092565b60005b8381101561094457818101518382015260200161092c565b50506000910152565b6000825161095f818460208701610929565b9190910192915050565b6020815260008251806020840152610988816040850160208701610929565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220a1af0d6cb4f1e31496a4c5c1448913bce4bd6ad3a39e47c6f7190c114d6f9bf464736f6c63430008110033",
|
| 50 |
-
"storage": {
|
| 51 |
-
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 52 |
-
"0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 53 |
-
"0x0000000000000000000000000000000000000000000000000000000000000068": "0x00000000000000a40d5f56745a118d0906a34e69aec8c0db1cb8fa0000000100",
|
| 54 |
-
"0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0x00000000000000000000000085ceb41028b1a5ed2b88e395145344837308b251",
|
| 55 |
-
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0x0000000000000000000000008bd36ca1a55e389335004872aa3c3be0969d3aa7"
|
| 56 |
-
}
|
| 57 |
-
},
|
| 58 |
-
{
|
| 59 |
-
"contractName": "PolygonZkEVMGlobalExitRootL2 implementation",
|
| 60 |
-
"balance": "0",
|
| 61 |
-
"nonce": "1",
|
| 62 |
-
"address": "0x282a631D9F3Ef04Bf1A44B4C9e8bDC8EB278917f",
|
| 63 |
-
"bytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806301fd904414610051578063257b36321461006d57806333d6247d1461008d578063a3c573eb146100a2575b600080fd5b61005a60015481565b6040519081526020015b60405180910390f35b61005a61007b366004610162565b60006020819052908152604090205481565b6100a061009b366004610162565b6100ee565b005b6100c97f000000000000000000000000528e26b25a34a4a5d0dbda1d57d318153d2ed58281565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610064565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000528e26b25a34a4a5d0dbda1d57d318153d2ed582161461015d576040517fb49365dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600155565b60006020828403121561017457600080fd5b503591905056fea2646970667358221220a187fc278346c1b61c449ea3641002b6eac2bda3351a122a12c35099f933696864736f6c63430008110033"
|
| 64 |
-
},
|
| 65 |
-
{
|
| 66 |
-
"contractName": "PolygonZkEVMGlobalExitRootL2 proxy",
|
| 67 |
-
"balance": "0",
|
| 68 |
-
"nonce": "1",
|
| 69 |
-
"address": "0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa",
|
| 70 |
-
"bytecode": "0x60806040523661001357610011610017565b005b6100115b61001f6101b7565b6001600160a01b0316336001600160a01b0316141561016f5760606001600160e01b031960003516631b2ce7f360e11b8114156100655761005e6101ea565b9150610167565b6001600160e01b0319811663278f794360e11b14156100865761005e610241565b6001600160e01b031981166308f2839760e41b14156100a75761005e610287565b6001600160e01b031981166303e1469160e61b14156100c85761005e6102b8565b6001600160e01b03198116635c60da1b60e01b14156100e95761005e6102f8565b60405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b815160208301f35b61017761030c565b565b606061019e83836040518060600160405280602781526020016108576027913961031c565b9392505050565b90565b6001600160a01b03163b151590565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b60606101f4610394565b600061020336600481846106a2565b81019061021091906106e8565b905061022d8160405180602001604052806000815250600061039f565b505060408051602081019091526000815290565b606060008061025336600481846106a2565b8101906102609190610719565b915091506102708282600161039f565b604051806020016040528060008152509250505090565b6060610291610394565b60006102a036600481846106a2565b8101906102ad91906106e8565b905061022d816103cb565b60606102c2610394565b60006102cc6101b7565b604080516001600160a01b03831660208201529192500160405160208183030381529060405291505090565b6060610302610394565b60006102cc610422565b610177610317610422565b610431565b6060600080856001600160a01b0316856040516103399190610807565b600060405180830381855af49150503d8060008114610374576040519150601f19603f3d011682016040523d82523d6000602084013e610379565b606091505b509150915061038a86838387610455565b9695505050505050565b341561017757600080fd5b6103a8836104d3565b6000825111806103b55750805b156103c6576103c48383610179565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103f46101b7565b604080516001600160a01b03928316815291841660208301520160405180910390a161041f81610513565b50565b600061042c6105bc565b905090565b3660008037600080366000845af43d6000803e808015610450573d6000f35b3d6000fd5b606083156104c15782516104ba576001600160a01b0385163b6104ba5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161015e565b50816104cb565b6104cb83836105e4565b949350505050565b6104dc8161060e565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105785760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b606482015260840161015e565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6101db565b8151156105f45781518083602001fd5b8060405162461bcd60e51b815260040161015e9190610823565b6001600160a01b0381163b61067b5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840161015e565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61059b565b600080858511156106b257600080fd5b838611156106bf57600080fd5b5050820193919092039150565b80356001600160a01b03811681146106e357600080fd5b919050565b6000602082840312156106fa57600080fd5b61019e826106cc565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561072c57600080fd5b610735836106cc565b9150602083013567ffffffffffffffff8082111561075257600080fd5b818501915085601f83011261076657600080fd5b81358181111561077857610778610703565b604051601f8201601f19908116603f011681019083821181831017156107a0576107a0610703565b816040528281528860208487010111156107b957600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b60005b838110156107f65781810151838201526020016107de565b838111156103c45750506000910152565b600082516108198184602087016107db565b9190910192915050565b60208152600082518060208401526108428160408501602087016107db565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122012bb4f564f73959a03513dc74fc3c6e40e8386e6f02c16b78d6db00ce0aa16af64736f6c63430008090033",
|
| 71 |
-
"storage": {
|
| 72 |
-
"0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0x00000000000000000000000085ceb41028b1a5ed2b88e395145344837308b251",
|
| 73 |
-
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0x000000000000000000000000282a631d9f3ef04bf1a44b4c9e8bdc8eb278917f"
|
| 74 |
-
}
|
| 75 |
-
},
|
| 76 |
-
{
|
| 77 |
-
"contractName": "PolygonZkEVMTimelock",
|
| 78 |
-
"balance": "0",
|
| 79 |
-
"nonce": "1",
|
| 80 |
-
"address": "0xdbC6981a11fc2B000c635bFA7C47676b25C87D39",
|
| 81 |
-
"bytecode": "0x6080604052600436106101c65760003560e01c806364d62353116100f7578063b1c5f42711610095578063d547741f11610064578063d547741f14610661578063e38335e514610681578063f23a6e6114610694578063f27a0c92146106d957600080fd5b8063b1c5f427146105af578063bc197c81146105cf578063c4d252f514610614578063d45c44351461063457600080fd5b80638f61f4f5116100d15780638f61f4f5146104e157806391d1485414610515578063a217fddf14610566578063b08e51c01461057b57600080fd5b806364d62353146104815780638065657f146104a15780638f2a0bb0146104c157600080fd5b8063248a9ca31161016457806331d507501161013e57806331d50750146103c857806336568abe146103e85780633a6aae7214610408578063584b153e1461046157600080fd5b8063248a9ca3146103475780632ab0f529146103775780632f2ff15d146103a857600080fd5b80630d3cf6fc116101a05780630d3cf6fc1461026b578063134008d31461029f57806313bc9f20146102b2578063150b7a02146102d257600080fd5b806301d5062a146101d257806301ffc9a7146101f457806307bd02651461022957600080fd5b366101cd57005b600080fd5b3480156101de57600080fd5b506101f26101ed366004611c52565b6106ee565b005b34801561020057600080fd5b5061021461020f366004611cc7565b610783565b60405190151581526020015b60405180910390f35b34801561023557600080fd5b5061025d7fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e6381565b604051908152602001610220565b34801561027757600080fd5b5061025d7f5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca581565b6101f26102ad366004611d09565b6107df565b3480156102be57600080fd5b506102146102cd366004611d75565b6108d7565b3480156102de57600080fd5b506103166102ed366004611e9a565b7f150b7a0200000000000000000000000000000000000000000000000000000000949350505050565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610220565b34801561035357600080fd5b5061025d610362366004611d75565b60009081526020819052604090206001015490565b34801561038357600080fd5b50610214610392366004611d75565b6000908152600160208190526040909120541490565b3480156103b457600080fd5b506101f26103c3366004611f02565b6108fd565b3480156103d457600080fd5b506102146103e3366004611d75565b610927565b3480156103f457600080fd5b506101f2610403366004611f02565b610940565b34801561041457600080fd5b5061043c7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610220565b34801561046d57600080fd5b5061021461047c366004611d75565b6109f8565b34801561048d57600080fd5b506101f261049c366004611d75565b610a0e565b3480156104ad57600080fd5b5061025d6104bc366004611d09565b610ade565b3480156104cd57600080fd5b506101f26104dc366004611f73565b610b1d565b3480156104ed57600080fd5b5061025d7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc181565b34801561052157600080fd5b50610214610530366004611f02565b60009182526020828152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b34801561057257600080fd5b5061025d600081565b34801561058757600080fd5b5061025d7ffd643c72710c63c0180259aba6b2d05451e3591a24e58b62239378085726f78381565b3480156105bb57600080fd5b5061025d6105ca366004612025565b610d4f565b3480156105db57600080fd5b506103166105ea36600461214e565b7fbc197c810000000000000000000000000000000000000000000000000000000095945050505050565b34801561062057600080fd5b506101f261062f366004611d75565b610d94565b34801561064057600080fd5b5061025d61064f366004611d75565b60009081526001602052604090205490565b34801561066d57600080fd5b506101f261067c366004611f02565b610e8f565b6101f261068f366004612025565b610eb4565b3480156106a057600080fd5b506103166106af3660046121f8565b7ff23a6e610000000000000000000000000000000000000000000000000000000095945050505050565b3480156106e557600080fd5b5061025d611161565b7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc161071881611244565b6000610728898989898989610ade565b90506107348184611251565b6000817f4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca8b8b8b8b8b8a604051610770969594939291906122a6565b60405180910390a3505050505050505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e00000000000000000000000000000000000000000000000000000000014806107d957506107d98261139e565b92915050565b600080527fdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d70696020527f5ba6852781629bcdcd4bdaa6de76d786f1c64b16acdac474e55bebc0ea157951547fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e639060ff1661085c5761085c8133611435565b600061086c888888888888610ade565b905061087881856114ed565b6108848888888861162a565b6000817fc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b588a8a8a8a6040516108bc94939291906122f1565b60405180910390a36108cd8161172e565b5050505050505050565b6000818152600160205260408120546001811180156108f65750428111155b9392505050565b60008281526020819052604090206001015461091881611244565b61092283836117d7565b505050565b60008181526001602052604081205481905b1192915050565b73ffffffffffffffffffffffffffffffffffffffff811633146109ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084015b60405180910390fd5b6109f482826118c7565b5050565b6000818152600160208190526040822054610939565b333014610a9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f54696d656c6f636b436f6e74726f6c6c65723a2063616c6c6572206d7573742060448201527f62652074696d656c6f636b00000000000000000000000000000000000000000060648201526084016109e1565b60025460408051918252602082018390527f11c24f4ead16507c69ac467fbd5e4eed5fb5c699626d2cc6d66421df253886d5910160405180910390a1600255565b6000868686868686604051602001610afb969594939291906122a6565b6040516020818303038152906040528051906020012090509695505050505050565b7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc1610b4781611244565b888714610bd6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b888514610c65576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b6000610c778b8b8b8b8b8b8b8b610d4f565b9050610c838184611251565b60005b8a811015610d415780827f4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca8e8e85818110610cc357610cc3612331565b9050602002016020810190610cd89190612360565b8d8d86818110610cea57610cea612331565b905060200201358c8c87818110610d0357610d03612331565b9050602002810190610d15919061237b565b8c8b604051610d29969594939291906122a6565b60405180910390a3610d3a8161240f565b9050610c86565b505050505050505050505050565b60008888888888888888604051602001610d709897969594939291906124f7565b60405160208183030381529060405280519060200120905098975050505050505050565b7ffd643c72710c63c0180259aba6b2d05451e3591a24e58b62239378085726f783610dbe81611244565b610dc7826109f8565b610e53576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20636160448201527f6e6e6f742062652063616e63656c6c656400000000000000000000000000000060648201526084016109e1565b6000828152600160205260408082208290555183917fbaa1eb22f2a492ba1a5fea61b8df4d27c6c8b5f3971e63bb58fa14ff72eedb7091a25050565b600082815260208190526040902060010154610eaa81611244565b61092283836118c7565b600080527fdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d70696020527f5ba6852781629bcdcd4bdaa6de76d786f1c64b16acdac474e55bebc0ea157951547fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e639060ff16610f3157610f318133611435565b878614610fc0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b87841461104f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b60006110618a8a8a8a8a8a8a8a610d4f565b905061106d81856114ed565b60005b8981101561114b5760008b8b8381811061108c5761108c612331565b90506020020160208101906110a19190612360565b905060008a8a848181106110b7576110b7612331565b9050602002013590503660008a8a868181106110d5576110d5612331565b90506020028101906110e7919061237b565b915091506110f78484848461162a565b84867fc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b588686868660405161112e94939291906122f1565b60405180910390a350505050806111449061240f565b9050611070565b506111558161172e565b50505050505050505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff161580159061123257507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166315064c966040518163ffffffff1660e01b8152600401602060405180830381865afa15801561120e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123291906125be565b1561123d5750600090565b5060025490565b61124e8133611435565b50565b61125a82610927565b156112e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20616c60448201527f7265616479207363686564756c6564000000000000000000000000000000000060648201526084016109e1565b6112ef611161565b81101561137e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f54696d656c6f636b436f6e74726f6c6c65723a20696e73756666696369656e7460448201527f2064656c6179000000000000000000000000000000000000000000000000000060648201526084016109e1565b61138881426125e0565b6000928352600160205260409092209190915550565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b0000000000000000000000000000000000000000000000000000000014806107d957507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146107d9565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166109f4576114738161197e565b61147e83602061199d565b60405160200161148f929190612617565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a00000000000000000000000000000000000000000000000000000000082526109e191600401612698565b6114f6826108d7565b611582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20697360448201527f206e6f742072656164790000000000000000000000000000000000000000000060648201526084016109e1565b80158061159e5750600081815260016020819052604090912054145b6109f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f54696d656c6f636b436f6e74726f6c6c65723a206d697373696e67206465706560448201527f6e64656e6379000000000000000000000000000000000000000000000000000060648201526084016109e1565b60008473ffffffffffffffffffffffffffffffffffffffff168484846040516116549291906126e9565b60006040518083038185875af1925050503d8060008114611691576040519150601f19603f3d011682016040523d82523d6000602084013e611696565b606091505b5050905080611727576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603360248201527f54696d656c6f636b436f6e74726f6c6c65723a20756e6465726c79696e67207460448201527f72616e73616374696f6e2072657665727465640000000000000000000000000060648201526084016109e1565b5050505050565b611737816108d7565b6117c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20697360448201527f206e6f742072656164790000000000000000000000000000000000000000000060648201526084016109e1565b600090815260016020819052604090912055565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166109f45760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556118693390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16156109f45760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60606107d973ffffffffffffffffffffffffffffffffffffffff831660145b606060006119ac8360026126f9565b6119b79060026125e0565b67ffffffffffffffff8111156119cf576119cf611d8e565b6040519080825280601f01601f1916602001820160405280156119f9576020820181803683370190505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110611a3057611a30612331565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611a9357611a93612331565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000611acf8460026126f9565b611ada9060016125e0565b90505b6001811115611b77577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110611b1b57611b1b612331565b1a60f81b828281518110611b3157611b31612331565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c93611b7081612710565b9050611add565b5083156108f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016109e1565b803573ffffffffffffffffffffffffffffffffffffffff81168114611c0457600080fd5b919050565b60008083601f840112611c1b57600080fd5b50813567ffffffffffffffff811115611c3357600080fd5b602083019150836020828501011115611c4b57600080fd5b9250929050565b600080600080600080600060c0888a031215611c6d57600080fd5b611c7688611be0565b965060208801359550604088013567ffffffffffffffff811115611c9957600080fd5b611ca58a828b01611c09565b989b979a50986060810135976080820135975060a09091013595509350505050565b600060208284031215611cd957600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146108f657600080fd5b60008060008060008060a08789031215611d2257600080fd5b611d2b87611be0565b955060208701359450604087013567ffffffffffffffff811115611d4e57600080fd5b611d5a89828a01611c09565b979a9699509760608101359660809091013595509350505050565b600060208284031215611d8757600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611e0457611e04611d8e565b604052919050565b600082601f830112611e1d57600080fd5b813567ffffffffffffffff811115611e3757611e37611d8e565b611e6860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611dbd565b818152846020838601011115611e7d57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215611eb057600080fd5b611eb985611be0565b9350611ec760208601611be0565b925060408501359150606085013567ffffffffffffffff811115611eea57600080fd5b611ef687828801611e0c565b91505092959194509250565b60008060408385031215611f1557600080fd5b82359150611f2560208401611be0565b90509250929050565b60008083601f840112611f4057600080fd5b50813567ffffffffffffffff811115611f5857600080fd5b6020830191508360208260051b8501011115611c4b57600080fd5b600080600080600080600080600060c08a8c031215611f9157600080fd5b893567ffffffffffffffff80821115611fa957600080fd5b611fb58d838e01611f2e565b909b50995060208c0135915080821115611fce57600080fd5b611fda8d838e01611f2e565b909950975060408c0135915080821115611ff357600080fd5b506120008c828d01611f2e565b9a9d999c50979a969997986060880135976080810135975060a0013595509350505050565b60008060008060008060008060a0898b03121561204157600080fd5b883567ffffffffffffffff8082111561205957600080fd5b6120658c838d01611f2e565b909a50985060208b013591508082111561207e57600080fd5b61208a8c838d01611f2e565b909850965060408b01359150808211156120a357600080fd5b506120b08b828c01611f2e565b999c989b509699959896976060870135966080013595509350505050565b600082601f8301126120df57600080fd5b8135602067ffffffffffffffff8211156120fb576120fb611d8e565b8160051b61210a828201611dbd565b928352848101820192828101908785111561212457600080fd5b83870192505b848310156121435782358252918301919083019061212a565b979650505050505050565b600080600080600060a0868803121561216657600080fd5b61216f86611be0565b945061217d60208701611be0565b9350604086013567ffffffffffffffff8082111561219a57600080fd5b6121a689838a016120ce565b945060608801359150808211156121bc57600080fd5b6121c889838a016120ce565b935060808801359150808211156121de57600080fd5b506121eb88828901611e0c565b9150509295509295909350565b600080600080600060a0868803121561221057600080fd5b61221986611be0565b945061222760208701611be0565b93506040860135925060608601359150608086013567ffffffffffffffff81111561225157600080fd5b6121eb88828901611e0c565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff8716815285602082015260a0604082015260006122dc60a08301868861225d565b60608301949094525060800152949350505050565b73ffffffffffffffffffffffffffffffffffffffff8516815283602082015260606040820152600061232760608301848661225d565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561237257600080fd5b6108f682611be0565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126123b057600080fd5b83018035915067ffffffffffffffff8211156123cb57600080fd5b602001915036819003821315611c4b57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612440576124406123e0565b5060010190565b81835260006020808501808196508560051b810191508460005b878110156124ea57828403895281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18836030181126124a057600080fd5b8701858101903567ffffffffffffffff8111156124bc57600080fd5b8036038213156124cb57600080fd5b6124d686828461225d565b9a87019a9550505090840190600101612461565b5091979650505050505050565b60a0808252810188905260008960c08301825b8b8110156125455773ffffffffffffffffffffffffffffffffffffffff61253084611be0565b1682526020928301929091019060010161250a565b5083810360208501528881527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff89111561257e57600080fd5b8860051b9150818a602083013701828103602090810160408501526125a69082018789612447565b60608401959095525050608001529695505050505050565b6000602082840312156125d057600080fd5b815180151581146108f657600080fd5b808201808211156107d9576107d96123e0565b60005b8381101561260e5781810151838201526020016125f6565b50506000910152565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161264f8160178501602088016125f3565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000601791840191820152835161268c8160288401602088016125f3565b01602801949350505050565b60208152600082518060208401526126b78160408501602087016125f3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b8183823760009101908152919050565b80820281158282048414176107d9576107d96123e0565b60008161271f5761271f6123e0565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea26469706673582212206416c4e08f97752b4bb06159524dac058d3dccd8775e57ef1b01505751ebf7af64736f6c63430008110033",
|
| 82 |
-
"storage": {
|
| 83 |
-
"0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000000e10",
|
| 84 |
-
"0xf587dde6f8846415188f807710a3304f72092565918b30307d60efdc8014f20b": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 85 |
-
"0x07020fe9de9b8274d1e6cc0668a6f6344a870f35e5a847590c8069dfa85ac78f": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 86 |
-
"0x64494413541ff93b31aa309254e3fed72a7456e9845988b915b4c7a7ceba8814": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5",
|
| 87 |
-
"0xc8e266e0814671642b74f3807affd27009fcc23f713ea92d1743e0ee0c1e7603": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 88 |
-
"0x3412d5605ac6cd444957cedb533e5dacad6378b4bc819ebe3652188a665066d6": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5",
|
| 89 |
-
"0x9b3efc411c5f69533db363941e091f6f3af8b7e306525413577a56d27e5dbe73": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 90 |
-
"0xdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d706a": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5",
|
| 91 |
-
"0xa2001bdd6a5944149e83176d089ee9a8246bd56aecf38fe4d6c66f5fbac18675": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 92 |
-
"0xc3ad33e20b0c56a223ad5104fff154aa010f8715b9c981fd38fdc60a4d1a52fc": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5"
|
| 93 |
-
}
|
| 94 |
-
},
|
| 95 |
-
{
|
| 96 |
-
"accountName": "keyless Deployer",
|
| 97 |
-
"balance": "0",
|
| 98 |
-
"nonce": "1",
|
| 99 |
-
"address": "0x1754175c450BEbB9B6E14dEe542649c0402A25d2"
|
| 100 |
-
},
|
| 101 |
-
{
|
| 102 |
-
"accountName": "deployer",
|
| 103 |
-
"balance": "100000000000000000000000",
|
| 104 |
-
"nonce": "8",
|
| 105 |
-
"address": "0xff6250d0E86A2465B0C1bF8e36409503d6a26963"
|
| 106 |
-
}
|
| 107 |
-
]
|
| 108 |
-
}
|
| 109 |
-
`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -2,6 +2,8 @@
|
|
| 2 |
|
| 3 |
import (
|
| 4 |
"bytes"
|
|
|
|
|
|
|
| 5 |
"path/filepath"
|
| 6 |
"strings"
|
| 7 |
|
|
@@ -21,6 +24,7 @@
|
|
| 21 |
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 22 |
"github.com/0xPolygonHermez/zkevm-node/state/runtime/executor"
|
| 23 |
"github.com/0xPolygonHermez/zkevm-node/synchronizer"
|
|
|
|
| 24 |
"github.com/mitchellh/mapstructure"
|
| 25 |
"github.com/spf13/viper"
|
| 26 |
"github.com/urfave/cli/v2"
|
|
@@ -31,7 +35,7 @@
|
|
| 31 |
FlagYes = "yes"
|
| 32 |
// FlagCfg is the flag for cfg.
|
| 33 |
FlagCfg = "cfg"
|
| 34 |
-
// FlagNetwork is the flag for the network name. Valid values: ["
|
| 35 |
FlagNetwork = "network"
|
| 36 |
// FlagCustomNetwork is the flag for the custom network file. This is required if --network=custom
|
| 37 |
FlagCustomNetwork = "custom-network-file"
|
|
@@ -183,3 +187,19 @@
|
|
| 183 |
}
|
| 184 |
return cfg, nil
|
| 185 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
|
| 3 |
import (
|
| 4 |
"bytes"
|
| 5 |
+
"crypto/ecdsa"
|
| 6 |
+
"os"
|
| 7 |
"path/filepath"
|
| 8 |
"strings"
|
| 9 |
|
|
|
|
| 24 |
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 25 |
"github.com/0xPolygonHermez/zkevm-node/state/runtime/executor"
|
| 26 |
"github.com/0xPolygonHermez/zkevm-node/synchronizer"
|
| 27 |
+
"github.com/ethereum/go-ethereum/accounts/keystore"
|
| 28 |
"github.com/mitchellh/mapstructure"
|
| 29 |
"github.com/spf13/viper"
|
| 30 |
"github.com/urfave/cli/v2"
|
|
|
|
| 35 |
FlagYes = "yes"
|
| 36 |
// FlagCfg is the flag for cfg.
|
| 37 |
FlagCfg = "cfg"
|
| 38 |
+
// FlagNetwork is the flag for the network name. Valid values: ["custom"].
|
| 39 |
FlagNetwork = "network"
|
| 40 |
// FlagCustomNetwork is the flag for the custom network file. This is required if --network=custom
|
| 41 |
FlagCustomNetwork = "custom-network-file"
|
|
|
|
| 187 |
}
|
| 188 |
return cfg, nil
|
| 189 |
}
|
| 190 |
+
|
| 191 |
+
// NewKeyFromKeystore creates a private key from a keystore file
|
| 192 |
+
func NewKeyFromKeystore(cfg types.KeystoreFileConfig) (*ecdsa.PrivateKey, error) {
|
| 193 |
+
if cfg.Path == "" && cfg.Password == "" {
|
| 194 |
+
return nil, nil
|
| 195 |
+
}
|
| 196 |
+
keystoreEncrypted, err := os.ReadFile(filepath.Clean(cfg.Path))
|
| 197 |
+
if err != nil {
|
| 198 |
+
return nil, err
|
| 199 |
+
}
|
| 200 |
+
key, err := keystore.DecryptKey(keystoreEncrypted, cfg.Password)
|
| 201 |
+
if err != nil {
|
| 202 |
+
return nil, err
|
| 203 |
+
}
|
| 204 |
+
return key.PrivateKey, nil
|
| 205 |
+
}
|
|
@@ -174,24 +174,28 @@
|
|
| 174 |
expectedValue: uint64(80000),
|
| 175 |
},
|
| 176 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
| 177 |
path: "Etherman.URL",
|
| 178 |
expectedValue: "http://localhost:8545",
|
| 179 |
},
|
| 180 |
{
|
| 181 |
path: "NetworkConfig.L1Config.L1ChainID",
|
| 182 |
-
expectedValue: uint64(
|
| 183 |
},
|
| 184 |
{
|
| 185 |
path: "NetworkConfig.L1Config.ZkEVMAddr",
|
| 186 |
-
expectedValue: common.HexToAddress("
|
| 187 |
},
|
| 188 |
{
|
| 189 |
path: "NetworkConfig.L1Config.PolAddr",
|
| 190 |
-
expectedValue: common.HexToAddress("
|
| 191 |
},
|
| 192 |
{
|
| 193 |
path: "NetworkConfig.L1Config.GlobalExitRootManagerAddr",
|
| 194 |
-
expectedValue: common.HexToAddress("
|
| 195 |
},
|
| 196 |
{
|
| 197 |
path: "Etherman.MultiGasProvider",
|
|
@@ -547,7 +551,8 @@
|
|
| 547 |
require.NoError(t, os.WriteFile(file.Name(), []byte("{}"), 0600))
|
| 548 |
|
| 549 |
flagSet := flag.NewFlagSet("", flag.PanicOnError)
|
| 550 |
-
flagSet.String(config.FlagNetwork, "
|
|
|
|
| 551 |
ctx := cli.NewContext(cli.NewApp(), flagSet, nil)
|
| 552 |
cfg, err := config.Load(ctx, true)
|
| 553 |
if err != nil {
|
|
@@ -585,7 +590,8 @@
|
|
| 585 |
}()
|
| 586 |
require.NoError(t, os.WriteFile(file.Name(), []byte("{}"), 0600))
|
| 587 |
flagSet := flag.NewFlagSet("", flag.PanicOnError)
|
| 588 |
-
flagSet.String(config.FlagNetwork, "
|
|
|
|
| 589 |
ctx := cli.NewContext(cli.NewApp(), flagSet, nil)
|
| 590 |
|
| 591 |
os.Setenv("ZKEVM_NODE_LOG_OUTPUTS", "a,b,c")
|
|
|
|
| 174 |
expectedValue: uint64(80000),
|
| 175 |
},
|
| 176 |
{
|
| 177 |
+
path: "SequenceSender.MaxBatchesForL1",
|
| 178 |
+
expectedValue: uint64(300),
|
| 179 |
+
},
|
| 180 |
+
{
|
| 181 |
path: "Etherman.URL",
|
| 182 |
expectedValue: "http://localhost:8545",
|
| 183 |
},
|
| 184 |
{
|
| 185 |
path: "NetworkConfig.L1Config.L1ChainID",
|
| 186 |
+
expectedValue: uint64(1337),
|
| 187 |
},
|
| 188 |
{
|
| 189 |
path: "NetworkConfig.L1Config.ZkEVMAddr",
|
| 190 |
+
expectedValue: common.HexToAddress("0x8dAF17A20c9DBA35f005b6324F493785D239719d"),
|
| 191 |
},
|
| 192 |
{
|
| 193 |
path: "NetworkConfig.L1Config.PolAddr",
|
| 194 |
+
expectedValue: common.HexToAddress("0x5FbDB2315678afecb367f032d93F642f64180aa3"),
|
| 195 |
},
|
| 196 |
{
|
| 197 |
path: "NetworkConfig.L1Config.GlobalExitRootManagerAddr",
|
| 198 |
+
expectedValue: common.HexToAddress("0x8A791620dd6260079BF849Dc5567aDC3F2FdC318"),
|
| 199 |
},
|
| 200 |
{
|
| 201 |
path: "Etherman.MultiGasProvider",
|
|
|
|
| 551 |
require.NoError(t, os.WriteFile(file.Name(), []byte("{}"), 0600))
|
| 552 |
|
| 553 |
flagSet := flag.NewFlagSet("", flag.PanicOnError)
|
| 554 |
+
flagSet.String(config.FlagNetwork, "custom", "")
|
| 555 |
+
flagSet.String(config.FlagCustomNetwork, "../test/config/test.genesis.config.json", "")
|
| 556 |
ctx := cli.NewContext(cli.NewApp(), flagSet, nil)
|
| 557 |
cfg, err := config.Load(ctx, true)
|
| 558 |
if err != nil {
|
|
|
|
| 590 |
}()
|
| 591 |
require.NoError(t, os.WriteFile(file.Name(), []byte("{}"), 0600))
|
| 592 |
flagSet := flag.NewFlagSet("", flag.PanicOnError)
|
| 593 |
+
flagSet.String(config.FlagNetwork, "custom", "")
|
| 594 |
+
flagSet.String(config.FlagCustomNetwork, "../test/config/test.genesis.config.json", "")
|
| 595 |
ctx := cli.NewContext(cli.NewApp(), flagSet, nil)
|
| 596 |
|
| 597 |
os.Setenv("ZKEVM_NODE_LOG_OUTPUTS", "a,b,c")
|
|
@@ -102,9 +102,18 @@
|
|
| 102 |
SyncInterval = "1s"
|
| 103 |
SyncChunkSize = 100
|
| 104 |
TrustedSequencerURL = "" # If it is empty or not specified, then the value is read from the smc
|
|
|
|
| 105 |
L1SynchronizationMode = "sequential"
|
| 106 |
L1SyncCheckL2BlockHash = true
|
| 107 |
-
L1SyncCheckL2BlockNumberhModulus =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 108 |
[Synchronizer.L1ParallelSynchronization]
|
| 109 |
MaxClients = 10
|
| 110 |
MaxPendingNoProcessedBlocks = 25
|
|
@@ -160,6 +169,7 @@
|
|
| 160 |
L2Coinbase = "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266"
|
| 161 |
PrivateKey = {Path = "/pk/sequencer.keystore", Password = "testonly"}
|
| 162 |
GasOffset = 80000
|
|
|
|
| 163 |
|
| 164 |
[Aggregator]
|
| 165 |
Host = "0.0.0.0"
|
|
@@ -174,6 +184,10 @@
|
|
| 174 |
GasOffset = 0
|
| 175 |
UpgradeEtrogBatchNumber = 0
|
| 176 |
BatchProofL1BlockConfirmations = 2
|
|
|
|
|
|
|
|
|
|
|
|
|
| 177 |
|
| 178 |
[L2GasPriceSuggester]
|
| 179 |
Type = "follower"
|
|
|
|
| 102 |
SyncInterval = "1s"
|
| 103 |
SyncChunkSize = 100
|
| 104 |
TrustedSequencerURL = "" # If it is empty or not specified, then the value is read from the smc
|
| 105 |
+
SyncBlockProtection = "safe" # latest, finalized, safe
|
| 106 |
L1SynchronizationMode = "sequential"
|
| 107 |
L1SyncCheckL2BlockHash = true
|
| 108 |
+
L1SyncCheckL2BlockNumberhModulus = 600
|
| 109 |
+
[Synchronizer.L1BlockCheck]
|
| 110 |
+
Enable = true
|
| 111 |
+
L1SafeBlockPoint = "finalized"
|
| 112 |
+
L1SafeBlockOffset = 0
|
| 113 |
+
ForceCheckBeforeStart = true
|
| 114 |
+
PreCheckEnable = true
|
| 115 |
+
L1PreSafeBlockPoint = "safe"
|
| 116 |
+
L1PreSafeBlockOffset = 0
|
| 117 |
[Synchronizer.L1ParallelSynchronization]
|
| 118 |
MaxClients = 10
|
| 119 |
MaxPendingNoProcessedBlocks = 25
|
|
|
|
| 169 |
L2Coinbase = "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266"
|
| 170 |
PrivateKey = {Path = "/pk/sequencer.keystore", Password = "testonly"}
|
| 171 |
GasOffset = 80000
|
| 172 |
+
MaxBatchesForL1 = 300
|
| 173 |
|
| 174 |
[Aggregator]
|
| 175 |
Host = "0.0.0.0"
|
|
|
|
| 184 |
GasOffset = 0
|
| 185 |
UpgradeEtrogBatchNumber = 0
|
| 186 |
BatchProofL1BlockConfirmations = 2
|
| 187 |
+
SettlementBackend = "agglayer"
|
| 188 |
+
AggLayerTxTimeout = "5m"
|
| 189 |
+
AggLayerURL = "http://zkevm-agglayer"
|
| 190 |
+
SequencerPrivateKey = {Path = "/pk/sequencer.keystore", Password = "testonly"}
|
| 191 |
|
| 192 |
[L2GasPriceSuggester]
|
| 193 |
Type = "follower"
|
|
@@ -1,108 +0,0 @@
|
|
| 1 |
-
package config
|
| 2 |
-
|
| 3 |
-
// MainnetNetworkConfigJSON is the hardcoded network configuration to be used for the official mainnet setup
|
| 4 |
-
const MainnetNetworkConfigJSON = `
|
| 5 |
-
{
|
| 6 |
-
"l1Config" : {
|
| 7 |
-
"chainId": 1,
|
| 8 |
-
"polygonZkEVMAddress": "0x519E42c24163192Dca44CD3fBDCEBF6be9130987",
|
| 9 |
-
"polygonRollupManagerAddress": "0x5132A183E9F3CB7C848b0AAC5Ae0c4f0491B7aB2",
|
| 10 |
-
"polTokenAddress": "0x455e53CBB86018Ac2B8092FdCd39d8444aFFC3F6",
|
| 11 |
-
"polygonZkEVMGlobalExitRootAddress": "0x580bda1e7A0CFAe92Fa7F6c20A3794F169CE3CFb"
|
| 12 |
-
},
|
| 13 |
-
"root": "0x3f86b09b43e3e49a41fc20a07579b79eba044253367817d5c241d23c0e2bc5c9",
|
| 14 |
-
"genesisBlockNumber": 16896721,
|
| 15 |
-
"genesis": [
|
| 16 |
-
{
|
| 17 |
-
"contractName": "PolygonZkEVMDeployer",
|
| 18 |
-
"balance": "0",
|
| 19 |
-
"nonce": "4",
|
| 20 |
-
"address": "0xCB19eDdE626906eB1EE52357a27F62dd519608C2",
|
| 21 |
-
"bytecode": "0x6080604052600436106100705760003560e01c8063715018a61161004e578063715018a6146100e65780638da5cb5b146100fb578063e11ae6cb14610126578063f2fde38b1461013957600080fd5b80632b79805a146100755780634a94d4871461008a5780636d07dbf81461009d575b600080fd5b610088610083366004610927565b610159565b005b6100886100983660046109c7565b6101cb565b3480156100a957600080fd5b506100bd6100b8366004610a1e565b61020d565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b50610088610220565b34801561010757600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166100bd565b610088610134366004610a40565b610234565b34801561014557600080fd5b50610088610154366004610a90565b61029b565b610161610357565b600061016e8585856103d8565b905061017a8183610537565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527fba82f25fed02cd2a23d9f5d11c2ef588d22af5437cbf23bfe61d87257c480e4c9060200160405180910390a15050505050565b6101d3610357565b6101de83838361057b565b506040517f25adb19089b6a549831a273acdf7908cff8b7ee5f551f8d1d37996cf01c5df5b90600090a1505050565b600061021983836105a9565b9392505050565b610228610357565b61023260006105b6565b565b61023c610357565b60006102498484846103d8565b60405173ffffffffffffffffffffffffffffffffffffffff821681529091507fba82f25fed02cd2a23d9f5d11c2ef588d22af5437cbf23bfe61d87257c480e4c9060200160405180910390a150505050565b6102a3610357565b73ffffffffffffffffffffffffffffffffffffffff811661034b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610354816105b6565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610232576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610342565b600083471015610444576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e63650000006044820152606401610342565b81516000036104af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f6044820152606401610342565b8282516020840186f5905073ffffffffffffffffffffffffffffffffffffffff8116610219576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f79000000000000006044820152606401610342565b6060610219838360006040518060400160405280601e81526020017f416464726573733a206c6f772d6c6576656c2063616c6c206661696c6564000081525061062b565b60606105a1848484604051806060016040528060298152602001610b3d6029913961062b565b949350505050565b6000610219838330610744565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060824710156106bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610342565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516106e69190610acf565b60006040518083038185875af1925050503d8060008114610723576040519150601f19603f3d011682016040523d82523d6000602084013e610728565b606091505b50915091506107398783838761076e565b979650505050505050565b6000604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b606083156108045782516000036107fd5773ffffffffffffffffffffffffffffffffffffffff85163b6107fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610342565b50816105a1565b6105a183838151156108195781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103429190610aeb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261088d57600080fd5b813567ffffffffffffffff808211156108a8576108a861084d565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156108ee576108ee61084d565b8160405283815286602085880101111561090757600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000806080858703121561093d57600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561096357600080fd5b61096f8883890161087c565b9350606087013591508082111561098557600080fd5b506109928782880161087c565b91505092959194509250565b803573ffffffffffffffffffffffffffffffffffffffff811681146109c257600080fd5b919050565b6000806000606084860312156109dc57600080fd5b6109e58461099e565b9250602084013567ffffffffffffffff811115610a0157600080fd5b610a0d8682870161087c565b925050604084013590509250925092565b60008060408385031215610a3157600080fd5b50508035926020909101359150565b600080600060608486031215610a5557600080fd5b8335925060208401359150604084013567ffffffffffffffff811115610a7a57600080fd5b610a868682870161087c565b9150509250925092565b600060208284031215610aa257600080fd5b6102198261099e565b60005b83811015610ac6578181015183820152602001610aae565b50506000910152565b60008251610ae1818460208701610aab565b9190910192915050565b6020815260008251806020840152610b0a816040850160208701610aab565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2063616c6c20776974682076616c7565206661696c6564a26469706673582212203e70ce334e8ec9d8d03e87415afd36dce4e82633bd277b08937095a6bd66367764736f6c63430008110033",
|
| 22 |
-
"storage": {
|
| 23 |
-
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000004c1665d6651ecefa59b9b3041951608468b18891"
|
| 24 |
-
}
|
| 25 |
-
},
|
| 26 |
-
{
|
| 27 |
-
"contractName": "ProxyAdmin",
|
| 28 |
-
"balance": "0",
|
| 29 |
-
"nonce": "1",
|
| 30 |
-
"address": "0x0F99738B2Fc14D77308337f3e2596b63aE7BCC4A",
|
| 31 |
-
"bytecode": "0x60806040526004361061007b5760003560e01c80639623609d1161004e5780639623609d1461012b57806399a88ec41461013e578063f2fde38b1461015e578063f3b7dead1461017e57600080fd5b8063204e1c7a14610080578063715018a6146100c95780637eff275e146100e05780638da5cb5b14610100575b600080fd5b34801561008c57600080fd5b506100a061009b366004610608565b61019e565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100d557600080fd5b506100de610255565b005b3480156100ec57600080fd5b506100de6100fb36600461062c565b610269565b34801561010c57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166100a0565b6100de610139366004610694565b6102f7565b34801561014a57600080fd5b506100de61015936600461062c565b61038c565b34801561016a57600080fd5b506100de610179366004610608565b6103e8565b34801561018a57600080fd5b506100a0610199366004610608565b6104a4565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907f5c60da1b00000000000000000000000000000000000000000000000000000000815260040190565b600060405180830381855afa9150503d8060008114610225576040519150601f19603f3d011682016040523d82523d6000602084013e61022a565b606091505b50915091508161023957600080fd5b8080602001905181019061024d9190610788565b949350505050565b61025d6104f0565b6102676000610571565b565b6102716104f0565b6040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690638f283970906024015b600060405180830381600087803b1580156102db57600080fd5b505af11580156102ef573d6000803e3d6000fd5b505050505050565b6102ff6104f0565b6040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690634f1ef28690349061035590869086906004016107a5565b6000604051808303818588803b15801561036e57600080fd5b505af1158015610382573d6000803e3d6000fd5b5050505050505050565b6103946104f0565b6040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690633659cfe6906024016102c1565b6103f06104f0565b73ffffffffffffffffffffffffffffffffffffffff8116610498576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6104a181610571565b50565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907ff851a44000000000000000000000000000000000000000000000000000000000815260040190565b60005473ffffffffffffffffffffffffffffffffffffffff163314610267576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161048f565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff811681146104a157600080fd5b60006020828403121561061a57600080fd5b8135610625816105e6565b9392505050565b6000806040838503121561063f57600080fd5b823561064a816105e6565b9150602083013561065a816105e6565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000606084860312156106a957600080fd5b83356106b4816105e6565b925060208401356106c4816105e6565b9150604084013567ffffffffffffffff808211156106e157600080fd5b818601915086601f8301126106f557600080fd5b81358181111561070757610707610665565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561074d5761074d610665565b8160405282815289602084870101111561076657600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b60006020828403121561079a57600080fd5b8151610625816105e6565b73ffffffffffffffffffffffffffffffffffffffff8316815260006020604081840152835180604085015260005b818110156107ef578581018301518582016060015282016107d3565b5060006060828601015260607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010192505050939250505056fea2646970667358221220372a0e10eebea1b7fa43ae4c976994e6ed01d85eedc3637b83f01d3f06be442064736f6c63430008110033",
|
| 32 |
-
"storage": {
|
| 33 |
-
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000bba0935fa93eb23de7990b47f0d96a8f75766d13"
|
| 34 |
-
}
|
| 35 |
-
},
|
| 36 |
-
{
|
| 37 |
-
"contractName": "PolygonZkEVMBridge implementation",
|
| 38 |
-
"balance": "0",
|
| 39 |
-
"nonce": "1",
|
| 40 |
-
"address": "0x5ac4182A1dd41AeEf465E40B82fd326BF66AB82C",
|
| 41 |
-
"bytecode": "0x6080604052600436106200019f5760003560e01c8063647c576c11620000e7578063be5831c71162000089578063dbc169761162000060578063dbc169761462000639578063ee25560b1462000651578063fb570834146200068257600080fd5b8063be5831c714620005ae578063cd58657914620005ea578063d02103ca146200060157600080fd5b80639e34070f11620000be5780639e34070f146200050a578063aaa13cc2146200054f578063bab161bf146200057457600080fd5b8063647c576c146200048657806379e2cf9714620004ab57806381b1c17414620004c357600080fd5b80632d2c9d94116200015157806334ac9cf2116200012857806334ac9cf2146200034b5780633ae05047146200037a5780633e197043146200039257600080fd5b80632d2c9d9414620002765780632dfdf0b5146200029b578063318aee3d14620002c257600080fd5b806322e95f2c116200018657806322e95f2c14620001ef578063240ff378146200023a5780632cffd02e146200025157600080fd5b806315064c9614620001a45780632072f6c514620001d5575b600080fd5b348015620001b157600080fd5b50606854620001c09060ff1681565b60405190151581526020015b60405180910390f35b348015620001e257600080fd5b50620001ed620006a7565b005b348015620001fc57600080fd5b50620002146200020e366004620032db565b62000705565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620001cc565b620001ed6200024b36600462003372565b620007a8565b3480156200025e57600080fd5b50620001ed6200027036600462003409565b620009d0565b3480156200028357600080fd5b50620001ed6200029536600462003409565b62000f74565b348015620002a857600080fd5b50620002b360535481565b604051908152602001620001cc565b348015620002cf57600080fd5b5062000319620002e1366004620034ef565b606b6020526000908152604090205463ffffffff811690640100000000900473ffffffffffffffffffffffffffffffffffffffff1682565b6040805163ffffffff909316835273ffffffffffffffffffffffffffffffffffffffff909116602083015201620001cc565b3480156200035857600080fd5b50606c54620002149073ffffffffffffffffffffffffffffffffffffffff1681565b3480156200038757600080fd5b50620002b362001178565b3480156200039f57600080fd5b50620002b3620003b136600462003526565b6040517fff0000000000000000000000000000000000000000000000000000000000000060f889901b1660208201527fffffffff0000000000000000000000000000000000000000000000000000000060e088811b821660218401527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606089811b821660258601529188901b909216603984015285901b16603d8201526051810183905260718101829052600090609101604051602081830303815290604052805190602001209050979650505050505050565b3480156200049357600080fd5b50620001ed620004a5366004620035b0565b6200125e565b348015620004b857600080fd5b50620001ed620014ad565b348015620004d057600080fd5b5062000214620004e236600462003600565b606a6020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b3480156200051757600080fd5b50620001c06200052936600462003600565b600881901c600090815260696020526040902054600160ff9092169190911b9081161490565b3480156200055c57600080fd5b50620002146200056e3660046200361a565b620014e7565b3480156200058157600080fd5b506068546200059890610100900463ffffffff1681565b60405163ffffffff9091168152602001620001cc565b348015620005bb57600080fd5b506068546200059890790100000000000000000000000000000000000000000000000000900463ffffffff1681565b620001ed620005fb366004620036ce565b620016d3565b3480156200060e57600080fd5b50606854620002149065010000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156200064657600080fd5b50620001ed62001c37565b3480156200065e57600080fd5b50620002b36200067036600462003600565b60696020526000908152604090205481565b3480156200068f57600080fd5b50620001c0620006a136600462003770565b62001c93565b606c5473ffffffffffffffffffffffffffffffffffffffff163314620006f9576040517fe2e8106b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6200070362001d7c565b565b6040805160e084901b7fffffffff0000000000000000000000000000000000000000000000000000000016602080830191909152606084901b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602483015282516018818403018152603890920183528151918101919091206000908152606a909152205473ffffffffffffffffffffffffffffffffffffffff165b92915050565b60685460ff1615620007e6576040517f2f0047fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60685463ffffffff8681166101009092041614806200080c5750600263ffffffff861610155b1562000844576040517f0595ea2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b6001606860019054906101000a900463ffffffff163388883488886053546040516200089a9998979695949392919062003806565b60405180910390a1620009b8620009b26001606860019054906101000a900463ffffffff16338989348989604051620008d592919062003881565b60405180910390206040517fff0000000000000000000000000000000000000000000000000000000000000060f889901b1660208201527fffffffff0000000000000000000000000000000000000000000000000000000060e088811b821660218401527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606089811b821660258601529188901b909216603984015285901b16603d8201526051810183905260718101829052600090609101604051602081830303815290604052805190602001209050979650505050505050565b62001e10565b8215620009c957620009c962001f27565b5050505050565b60685460ff161562000a0e576040517f2f0047fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62000a258b8b8b8b8b8b8b8b8b8b8b600062001ffc565b73ffffffffffffffffffffffffffffffffffffffff861662000b01576040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff861690859060405162000a7a9190620038e6565b60006040518083038185875af1925050503d806000811462000ab9576040519150601f19603f3d011682016040523d82523d6000602084013e62000abe565b606091505b505090508062000afa576040517f6747a28800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5062000efc565b60685463ffffffff61010090910481169088160362000b435762000b3d73ffffffffffffffffffffffffffffffffffffffff87168585620021ed565b62000efc565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e089901b1660208201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b166024820152600090603801604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152606a90935291205490915073ffffffffffffffffffffffffffffffffffffffff168062000e6e576000808062000c1886880188620039fb565b92509250925060008584848460405162000c329062003292565b62000c409392919062003abd565b8190604051809103906000f590508015801562000c61573d6000803e3d6000fd5b506040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8c81166004830152602482018c9052919250908216906340c10f1990604401600060405180830381600087803b15801562000cd757600080fd5b505af115801562000cec573d6000803e3d6000fd5b5050505080606a600088815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060405180604001604052808e63ffffffff1681526020018d73ffffffffffffffffffffffffffffffffffffffff16815250606b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050507f490e59a1701b938786ac72570a1efeac994a3dbe96e2e883e19e902ace6e6a398d8d838b8b60405162000e5c95949392919062003afa565b60405180910390a15050505062000ef9565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8781166004830152602482018790528216906340c10f1990604401600060405180830381600087803b15801562000edf57600080fd5b505af115801562000ef4573d6000803e3d6000fd5b505050505b50505b6040805163ffffffff8c811682528916602082015273ffffffffffffffffffffffffffffffffffffffff88811682840152861660608201526080810185905290517f25308c93ceeed162da955b3f7ce3e3f93606579e40fb92029faa9efe275459839181900360a00190a15050505050505050505050565b60685460ff161562000fb2576040517f2f0047fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62000fc98b8b8b8b8b8b8b8b8b8b8b600162001ffc565b60008473ffffffffffffffffffffffffffffffffffffffff1684888a868660405160240162000ffc949392919062003b42565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1806b5f200000000000000000000000000000000000000000000000000000000179052516200107f9190620038e6565b60006040518083038185875af1925050503d8060008114620010be576040519150601f19603f3d011682016040523d82523d6000602084013e620010c3565b606091505b5050905080620010ff576040517f37e391c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805163ffffffff8d811682528a16602082015273ffffffffffffffffffffffffffffffffffffffff89811682840152871660608201526080810186905290517f25308c93ceeed162da955b3f7ce3e3f93606579e40fb92029faa9efe275459839181900360a00190a1505050505050505050505050565b605354600090819081805b602081101562001255578083901c600116600103620011e65760338160208110620011b257620011b262003b8a565b0154604080516020810192909252810185905260600160405160208183030381529060405280519060200120935062001213565b60408051602081018690529081018390526060016040516020818303038152906040528051906020012093505b604080516020810184905290810183905260600160405160208183030381529060405280519060200120915080806200124c9062003be8565b91505062001183565b50919392505050565b600054610100900460ff16158080156200127f5750600054600160ff909116105b806200129b5750303b1580156200129b575060005460ff166001145b6200132d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156200138c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b606880547fffffffffffffff000000000000000000000000000000000000000000000000ff1661010063ffffffff8716027fffffffffffffff0000000000000000000000000000000000000000ffffffffff16176501000000000073ffffffffffffffffffffffffffffffffffffffff8681169190910291909117909155606c80547fffffffffffffffffffffffff00000000000000000000000000000000000000001691841691909117905562001443620022c3565b8015620014a757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b605354606854790100000000000000000000000000000000000000000000000000900463ffffffff16101562000703576200070362001f27565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e089901b1660208201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b1660248201526000908190603801604051602081830303815290604052805190602001209050600060ff60f81b3083604051806020016200157d9062003292565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f909101166040819052620015c8908d908d908d908d908d9060200162003c23565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905262001606929160200162003c64565b604051602081830303815290604052805190602001206040516020016200168f94939291907fff0000000000000000000000000000000000000000000000000000000000000094909416845260609290921b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660018401526015830152603582015260550190565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101209a9950505050505050505050565b60685460ff161562001711576040517f2f0047fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6200171b62002366565b60685463ffffffff888116610100909204161480620017415750600263ffffffff881610155b1562001779576040517f0595ea2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060608773ffffffffffffffffffffffffffffffffffffffff8816620017df57883414620017d5576040517fb89240f500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000925062001ad9565b341562001818576040517f798ee6f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8089166000908152606b602090815260409182902082518084019093525463ffffffff811683526401000000009004909216918101829052901562001908576040517f9dc29fac000000000000000000000000000000000000000000000000000000008152336004820152602481018b905273ffffffffffffffffffffffffffffffffffffffff8a1690639dc29fac90604401600060405180830381600087803b158015620018db57600080fd5b505af1158015620018f0573d6000803e3d6000fd5b50505050806020015194508060000151935062001ad7565b85156200191d576200191d898b8989620023db565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8b16906370a0823190602401602060405180830381865afa1580156200198b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620019b1919062003c97565b9050620019d773ffffffffffffffffffffffffffffffffffffffff8b1633308e620028f9565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8c16906370a0823190602401602060405180830381865afa15801562001a45573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001a6b919062003c97565b905062001a79828262003cb1565b6068548c9850610100900463ffffffff169650935062001a998762002959565b62001aa48c62002a71565b62001aaf8d62002b7e565b60405160200162001ac39392919062003abd565b604051602081830303815290604052945050505b505b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b600084868e8e868860535460405162001b1b98979695949392919062003cc7565b60405180910390a162001c0f620009b2600085878f8f8789805190602001206040517fff0000000000000000000000000000000000000000000000000000000000000060f889901b1660208201527fffffffff0000000000000000000000000000000000000000000000000000000060e088811b821660218401527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606089811b821660258601529188901b909216603984015285901b16603d8201526051810183905260718101829052600090609101604051602081830303815290604052805190602001209050979650505050505050565b861562001c205762001c2062001f27565b5050505062001c2e60018055565b50505050505050565b606c5473ffffffffffffffffffffffffffffffffffffffff16331462001c89576040517fe2e8106b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6200070362002c80565b600084815b602081101562001d6e57600163ffffffff8616821c8116900362001d0a5785816020811062001ccb5762001ccb62003b8a565b60200201358260405160200162001cec929190918252602082015260400190565b60405160208183030381529060405280519060200120915062001d59565b8186826020811062001d205762001d2062003b8a565b602002013560405160200162001d40929190918252602082015260400190565b6040516020818303038152906040528051906020012091505b8062001d658162003be8565b91505062001c98565b50821490505b949350505050565b60685460ff161562001dba576040517f2f0047fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040517f2261efe5aef6fedc1fd1550b25facc9181745623049c7901287030b9ad1a549790600090a1565b80600162001e216020600262003e79565b62001e2d919062003cb1565b6053541062001e68576040517fef5ccf6600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060536000815462001e7b9062003be8565b9182905550905060005b602081101562001f17578082901c60011660010362001ebd57826033826020811062001eb55762001eb562003b8a565b015550505050565b6033816020811062001ed35762001ed362003b8a565b01546040805160208101929092528101849052606001604051602081830303815290604052805190602001209250808062001f0e9062003be8565b91505062001e85565b5062001f2262003e87565b505050565b6053546068805463ffffffff909216790100000000000000000000000000000000000000000000000000027fffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffffff909216919091179081905573ffffffffffffffffffffffffffffffffffffffff65010000000000909104166333d6247d62001fad62001178565b6040518263ffffffff1660e01b815260040162001fcc91815260200190565b600060405180830381600087803b15801562001fe757600080fd5b505af1158015620014a7573d6000803e3d6000fd5b6200200d8b63ffffffff1662002d10565b6068546040805160208082018e90528183018d9052825180830384018152606083019384905280519101207f257b363200000000000000000000000000000000000000000000000000000000909252606481019190915260009165010000000000900473ffffffffffffffffffffffffffffffffffffffff169063257b3632906084016020604051808303816000875af1158015620020b0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620020d6919062003c97565b90508060000362002112576040517e2f6fad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60685463ffffffff88811661010090920416146200215c576040517f0595ea2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606854600090610100900463ffffffff166200217a5750896200217d565b508a5b620021a66200219d848c8c8c8c8c8c8c604051620008d592919062003881565b8f8f8462001c93565b620021dd576040517fe0417cec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905262001f229084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915262002d75565b600054610100900460ff166200235c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162001324565b6200070362002e88565b600260015403620023d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640162001324565b6002600155565b6000620023ec600482848662003eb6565b620023f79162003ee2565b90507f2afa5331000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000821601620026765760008080808080806200245a896004818d62003eb6565b81019062002469919062003f2b565b96509650965096509650965096503373ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614620024dd576040517f912ecce700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff861630146200252d576040517f750643af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8a851462002567576040517f03fffc4b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805173ffffffffffffffffffffffffffffffffffffffff89811660248301528881166044830152606482018890526084820187905260ff861660a483015260c4820185905260e48083018590528351808403909101815261010490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd505accf000000000000000000000000000000000000000000000000000000001790529151918e1691620026229190620038e6565b6000604051808303816000865af19150503d806000811462002661576040519150601f19603f3d011682016040523d82523d6000602084013e62002666565b606091505b50505050505050505050620009c9565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f8fcbaf0c0000000000000000000000000000000000000000000000000000000014620026f2576040517fe282c0ba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808080808080806200270a8a6004818e62003eb6565b81019062002719919062003f86565b975097509750975097509750975097503373ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff16146200278f576040517f912ecce700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87163014620027df576040517f750643af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805173ffffffffffffffffffffffffffffffffffffffff8a811660248301528981166044830152606482018990526084820188905286151560a483015260ff861660c483015260e482018590526101048083018590528351808403909101815261012490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f8fcbaf0c000000000000000000000000000000000000000000000000000000001790529151918f1691620028a39190620038e6565b6000604051808303816000865af19150503d8060008114620028e2576040519150601f19603f3d011682016040523d82523d6000602084013e620028e7565b606091505b50505050505050505050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052620014a79085907f23b872dd000000000000000000000000000000000000000000000000000000009060840162002240565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f06fdde03000000000000000000000000000000000000000000000000000000001790529051606091600091829173ffffffffffffffffffffffffffffffffffffffff861691620029dd9190620038e6565b600060405180830381855afa9150503d806000811462002a1a576040519150601f19603f3d011682016040523d82523d6000602084013e62002a1f565b606091505b50915091508162002a66576040518060400160405280600781526020017f4e4f5f4e414d450000000000000000000000000000000000000000000000000081525062001d74565b62001d748162002f21565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f95d89b41000000000000000000000000000000000000000000000000000000001790529051606091600091829173ffffffffffffffffffffffffffffffffffffffff86169162002af59190620038e6565b600060405180830381855afa9150503d806000811462002b32576040519150601f19603f3d011682016040523d82523d6000602084013e62002b37565b606091505b50915091508162002a66576040518060400160405280600981526020017f4e4f5f53594d424f4c000000000000000000000000000000000000000000000081525062001d74565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f313ce5670000000000000000000000000000000000000000000000000000000017905290516000918291829173ffffffffffffffffffffffffffffffffffffffff86169162002c019190620038e6565b600060405180830381855afa9150503d806000811462002c3e576040519150601f19603f3d011682016040523d82523d6000602084013e62002c43565b606091505b509150915081801562002c57575080516020145b62002c6457601262001d74565b8080602001905181019062001d74919062004012565b60018055565b60685460ff1662002cbd576040517f5386698100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040517f1e5e34eea33501aecf2ebec9fe0e884a40804275ea7fe10b2ba084c8374308b390600090a1565b600881901c60008181526069602052604081208054600160ff861690811b91821892839055929091908183169003620009c9576040517f646cf55800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600062002dd9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16620031119092919063ffffffff16565b80519091501562001f22578080602001905181019062002dfa919062004032565b62001f22576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840162001324565b600054610100900460ff1662002c7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162001324565b6060604082511062002f435781806020019051810190620007a2919062004052565b8151602003620030d35760005b60208110801562002f9b575082818151811062002f715762002f7162003b8a565b01602001517fff000000000000000000000000000000000000000000000000000000000000001615155b1562002fb6578062002fad8162003be8565b91505062002f50565b8060000362002ffa57505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e4700000000000000000000000000006020820152919050565b60008167ffffffffffffffff81111562003018576200301862003891565b6040519080825280601f01601f19166020018201604052801562003043576020820181803683370190505b50905060005b82811015620030cb5784818151811062003067576200306762003b8a565b602001015160f81c60f81b82828151811062003087576200308762003b8a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535080620030c28162003be8565b91505062003049565b509392505050565b505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e470000000000000000000000000000602082015290565b919050565b606062001d748484600085856000808673ffffffffffffffffffffffffffffffffffffffff168587604051620031489190620038e6565b60006040518083038185875af1925050503d806000811462003187576040519150601f19603f3d011682016040523d82523d6000602084013e6200318c565b606091505b50915091506200319f87838387620031aa565b979650505050505050565b60608315620032455782516000036200323d5773ffffffffffffffffffffffffffffffffffffffff85163b6200323d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162001324565b508162001d74565b62001d7483838151156200325c5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620013249190620040d2565b611b6680620040e883390190565b803563ffffffff811681146200310c57600080fd5b73ffffffffffffffffffffffffffffffffffffffff81168114620032d857600080fd5b50565b60008060408385031215620032ef57600080fd5b620032fa83620032a0565b915060208301356200330c81620032b5565b809150509250929050565b8015158114620032d857600080fd5b60008083601f8401126200333957600080fd5b50813567ffffffffffffffff8111156200335257600080fd5b6020830191508360208285010111156200336b57600080fd5b9250929050565b6000806000806000608086880312156200338b57600080fd5b6200339686620032a0565b94506020860135620033a881620032b5565b93506040860135620033ba8162003317565b9250606086013567ffffffffffffffff811115620033d757600080fd5b620033e58882890162003326565b969995985093965092949392505050565b806104008101831015620007a257600080fd5b60008060008060008060008060008060006105208c8e0312156200342c57600080fd5b620034388d8d620033f6565b9a50620034496104008d01620032a0565b99506104208c013598506104408c013597506200346a6104608d01620032a0565b96506104808c01356200347d81620032b5565b95506200348e6104a08d01620032a0565b94506104c08c0135620034a181620032b5565b93506104e08c013592506105008c013567ffffffffffffffff811115620034c757600080fd5b620034d58e828f0162003326565b915080935050809150509295989b509295989b9093969950565b6000602082840312156200350257600080fd5b81356200350f81620032b5565b9392505050565b60ff81168114620032d857600080fd5b600080600080600080600060e0888a0312156200354257600080fd5b87356200354f8162003516565b96506200355f60208901620032a0565b955060408801356200357181620032b5565b94506200358160608901620032a0565b935060808801356200359381620032b5565b9699959850939692959460a0840135945060c09093013592915050565b600080600060608486031215620035c657600080fd5b620035d184620032a0565b92506020840135620035e381620032b5565b91506040840135620035f581620032b5565b809150509250925092565b6000602082840312156200361357600080fd5b5035919050565b600080600080600080600060a0888a0312156200363657600080fd5b6200364188620032a0565b965060208801356200365381620032b5565b9550604088013567ffffffffffffffff808211156200367157600080fd5b6200367f8b838c0162003326565b909750955060608a01359150808211156200369957600080fd5b50620036a88a828b0162003326565b9094509250506080880135620036be8162003516565b8091505092959891949750929550565b600080600080600080600060c0888a031215620036ea57600080fd5b620036f588620032a0565b965060208801356200370781620032b5565b95506040880135945060608801356200372081620032b5565b93506080880135620037328162003317565b925060a088013567ffffffffffffffff8111156200374f57600080fd5b6200375d8a828b0162003326565b989b979a50959850939692959293505050565b60008060008061046085870312156200378857600080fd5b843593506200379b8660208701620033f6565b9250620037ac6104208601620032a0565b939692955092936104400135925050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b600061010060ff8c16835263ffffffff808c16602085015273ffffffffffffffffffffffffffffffffffffffff808c166040860152818b166060860152808a166080860152508760a08501528160c0850152620038678285018789620037bd565b925080851660e085015250509a9950505050505050505050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60005b83811015620038dd578181015183820152602001620038c3565b50506000910152565b60008251620038fa818460208701620038c0565b9190910192915050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156200394e576200394e62003891565b604052919050565b600067ffffffffffffffff82111562003973576200397362003891565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112620039b157600080fd5b8135620039c8620039c28262003956565b62003904565b818152846020838601011115620039de57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060006060848603121562003a1157600080fd5b833567ffffffffffffffff8082111562003a2a57600080fd5b62003a38878388016200399f565b9450602086013591508082111562003a4f57600080fd5b5062003a5e868287016200399f565b9250506040840135620035f58162003516565b6000815180845262003a8b816020860160208601620038c0565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60608152600062003ad2606083018662003a71565b828103602084015262003ae6818662003a71565b91505060ff83166040830152949350505050565b63ffffffff86168152600073ffffffffffffffffffffffffffffffffffffffff8087166020840152808616604084015250608060608301526200319f608083018486620037bd565b73ffffffffffffffffffffffffffffffffffffffff8516815263ffffffff8416602082015260606040820152600062003b80606083018486620037bd565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820362003c1c5762003c1c62003bb9565b5060010190565b60608152600062003c39606083018789620037bd565b828103602084015262003c4e818688620037bd565b91505060ff831660408301529695505050505050565b6000835162003c78818460208801620038c0565b83519083019062003c8e818360208801620038c0565b01949350505050565b60006020828403121562003caa57600080fd5b5051919050565b81810381811115620007a257620007a262003bb9565b600061010060ff8b16835263ffffffff808b16602085015273ffffffffffffffffffffffffffffffffffffffff808b166040860152818a1660608601528089166080860152508660a08501528160c085015262003d278285018762003a71565b925080851660e085015250509998505050505050505050565b600181815b8085111562003d9f57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111562003d835762003d8362003bb9565b8085161562003d9157918102915b93841c939080029062003d45565b509250929050565b60008262003db857506001620007a2565b8162003dc757506000620007a2565b816001811462003de0576002811462003deb5762003e0b565b6001915050620007a2565b60ff84111562003dff5762003dff62003bb9565b50506001821b620007a2565b5060208310610133831016604e8410600b841016171562003e30575081810a620007a2565b62003e3c838362003d40565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111562003e715762003e7162003bb9565b029392505050565b60006200350f838362003da7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b6000808585111562003ec757600080fd5b8386111562003ed557600080fd5b5050820193919092039150565b7fffffffff00000000000000000000000000000000000000000000000000000000813581811691600485101562003f235780818660040360031b1b83161692505b505092915050565b600080600080600080600060e0888a03121562003f4757600080fd5b873562003f5481620032b5565b9650602088013562003f6681620032b5565b955060408801359450606088013593506080880135620035938162003516565b600080600080600080600080610100898b03121562003fa457600080fd5b883562003fb181620032b5565b9750602089013562003fc381620032b5565b96506040890135955060608901359450608089013562003fe38162003317565b935060a089013562003ff58162003516565b979a969950949793969295929450505060c08201359160e0013590565b6000602082840312156200402557600080fd5b81516200350f8162003516565b6000602082840312156200404557600080fd5b81516200350f8162003317565b6000602082840312156200406557600080fd5b815167ffffffffffffffff8111156200407d57600080fd5b8201601f810184136200408f57600080fd5b8051620040a0620039c28262003956565b818152856020838501011115620040b657600080fd5b620040c9826020830160208601620038c0565b95945050505050565b6020815260006200350f602083018462003a7156fe6101006040523480156200001257600080fd5b5060405162001b6638038062001b6683398101604081905262000035916200028d565b82826003620000458382620003a1565b506004620000548282620003a1565b50503360c0525060ff811660e052466080819052620000739062000080565b60a052506200046d915050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f620000ad6200012e565b805160209182012060408051808201825260018152603160f81b90840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b6060600380546200013f9062000312565b80601f01602080910402602001604051908101604052809291908181526020018280546200016d9062000312565b8015620001be5780601f106200019257610100808354040283529160200191620001be565b820191906000526020600020905b815481529060010190602001808311620001a057829003601f168201915b5050505050905090565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001f057600080fd5b81516001600160401b03808211156200020d576200020d620001c8565b604051601f8301601f19908116603f01168101908282118183101715620002385762000238620001c8565b816040528381526020925086838588010111156200025557600080fd5b600091505b838210156200027957858201830151818301840152908201906200025a565b600093810190920192909252949350505050565b600080600060608486031215620002a357600080fd5b83516001600160401b0380821115620002bb57600080fd5b620002c987838801620001de565b94506020860151915080821115620002e057600080fd5b50620002ef86828701620001de565b925050604084015160ff811681146200030757600080fd5b809150509250925092565b600181811c908216806200032757607f821691505b6020821081036200034857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200039c57600081815260208120601f850160051c81016020861015620003775750805b601f850160051c820191505b81811015620003985782815560010162000383565b5050505b505050565b81516001600160401b03811115620003bd57620003bd620001c8565b620003d581620003ce845462000312565b846200034e565b602080601f8311600181146200040d5760008415620003f45750858301515b600019600386901b1c1916600185901b17855562000398565b600085815260208120601f198616915b828110156200043e578886015182559484019460019091019084016200041d565b50858210156200045d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e0516116aa620004bc6000396000610237015260008181610307015281816105c001526106a70152600061053a015260008181610379015261050401526116aa6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063a457c2d71161008c578063d505accf11610066578063d505accf1461039b578063dd62ed3e146103ae578063ffa1ad74146103f457600080fd5b8063a457c2d71461034e578063a9059cbb14610361578063cd0d00961461037457600080fd5b806395d89b41116100bd57806395d89b41146102e75780639dc29fac146102ef578063a3c573eb1461030257600080fd5b806370a08231146102915780637ecebe00146102c757600080fd5b806330adf81f1161012f5780633644e515116101145780633644e51514610261578063395093511461026957806340c10f191461027c57600080fd5b806330adf81f14610209578063313ce5671461023057600080fd5b806318160ddd1161016057806318160ddd146101bd57806320606b70146101cf57806323b872dd146101f657600080fd5b806306fdde031461017c578063095ea7b31461019a575b600080fd5b610184610430565b60405161019191906113e4565b60405180910390f35b6101ad6101a8366004611479565b6104c2565b6040519015158152602001610191565b6002545b604051908152602001610191565b6101c17f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b6101ad6102043660046114a3565b6104dc565b6101c17f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610191565b6101c1610500565b6101ad610277366004611479565b61055c565b61028f61028a366004611479565b6105a8565b005b6101c161029f3660046114df565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101c16102d53660046114df565b60056020526000908152604090205481565b610184610680565b61028f6102fd366004611479565b61068f565b6103297f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610191565b6101ad61035c366004611479565b61075e565b6101ad61036f366004611479565b61082f565b6101c17f000000000000000000000000000000000000000000000000000000000000000081565b61028f6103a9366004611501565b61083d565b6101c16103bc366004611574565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101846040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525081565b60606003805461043f906115a7565b80601f016020809104026020016040519081016040528092919081815260200182805461046b906115a7565b80156104b85780601f1061048d576101008083540402835291602001916104b8565b820191906000526020600020905b81548152906001019060200180831161049b57829003601f168201915b5050505050905090565b6000336104d0818585610b73565b60019150505b92915050565b6000336104ea858285610d27565b6104f5858585610dfe565b506001949350505050565b60007f00000000000000000000000000000000000000000000000000000000000000004614610537576105324661106d565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906104d090829086906105a3908790611629565b610b73565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60448201527f6c79676f6e5a6b45564d4272696467650000000000000000000000000000000060648201526084015b60405180910390fd5b61067c8282611135565b5050565b60606004805461043f906115a7565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610754576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60448201527f6c79676f6e5a6b45564d427269646765000000000000000000000000000000006064820152608401610669565b61067c8282611228565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610822576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610669565b6104f58286868403610b73565b6000336104d0818585610dfe565b834211156108cc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f546f6b656e577261707065643a3a7065726d69743a204578706972656420706560448201527f726d6974000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260056020526040812080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918a918a918a9190866109268361163c565b9091555060408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610991610500565b6040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281019190915260428101839052606201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600080855291840180845281905260ff89169284019290925260608301879052608083018690529092509060019060a0016020604051602081039080840390855afa158015610a55573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811615801590610ad057508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b610b5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f546f6b656e577261707065643a3a7065726d69743a20496e76616c696420736960448201527f676e6174757265000000000000000000000000000000000000000000000000006064820152608401610669565b610b678a8a8a610b73565b50505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8216610cb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610df85781811015610deb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610669565b610df88484848403610b73565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610ea1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8216610f44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610ffa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610df8565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f611098610430565b8051602091820120604080518082018252600181527f310000000000000000000000000000000000000000000000000000000000000090840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b73ffffffffffffffffffffffffffffffffffffffff82166111b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610669565b80600260008282546111c49190611629565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff82166112cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015611381576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610d1a565b600060208083528351808285015260005b81811015611411578581018301518582016040015282016113f5565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461147457600080fd5b919050565b6000806040838503121561148c57600080fd5b61149583611450565b946020939093013593505050565b6000806000606084860312156114b857600080fd5b6114c184611450565b92506114cf60208501611450565b9150604084013590509250925092565b6000602082840312156114f157600080fd5b6114fa82611450565b9392505050565b600080600080600080600060e0888a03121561151c57600080fd5b61152588611450565b965061153360208901611450565b95506040880135945060608801359350608088013560ff8116811461155757600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561158757600080fd5b61159083611450565b915061159e60208401611450565b90509250929050565b600181811c908216806115bb57607f821691505b6020821081036115f4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156104d6576104d66115fa565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361166d5761166d6115fa565b506001019056fea26469706673582212208d88fee561cff7120d381c345cfc534cef8229a272dc5809d4bbb685ad67141164736f6c63430008110033a2646970667358221220d9b3ca7b13ec80ac58634ddf0ecebe71e209a71f532614949b9e720413f50c8364736f6c63430008110033"
|
| 42 |
-
},
|
| 43 |
-
{
|
| 44 |
-
"contractName": "PolygonZkEVMBridge proxy",
|
| 45 |
-
"balance": "200000000000000000000000000",
|
| 46 |
-
"nonce": "1",
|
| 47 |
-
"address": "0x2a3DD3EB832aF982ec71669E178424b10Dca2EDe",
|
| 48 |
-
"bytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461088b565b610135565b61006b6100a33660046108a6565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461088b565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109bb602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b600061022161052a565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b61042283610552565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a16101748161059f565b60606000808573ffffffffffffffffffffffffffffffffffffffff16856040516104cf919061094d565b600060405180830381855af49150503d806000811461050a576040519150601f19603f3d011682016040523d82523d6000602084013e61050f565b606091505b5091509150610520868383876106ab565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b61055b81610753565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff8116610642576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561074157825160000361073a5773ffffffffffffffffffffffffffffffffffffffff85163b61073a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016103a2565b508161074b565b61074b838361081e565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff81163b6107f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610665565b81511561082e5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610969565b803573ffffffffffffffffffffffffffffffffffffffff8116811461088657600080fd5b919050565b60006020828403121561089d57600080fd5b6102b182610862565b6000806000604084860312156108bb57600080fd5b6108c484610862565b9250602084013567ffffffffffffffff808211156108e157600080fd5b818601915086601f8301126108f557600080fd5b81358181111561090457600080fd5b87602082850101111561091657600080fd5b6020830194508093505050509250925092565b60005b8381101561094457818101518382015260200161092c565b50506000910152565b6000825161095f818460208701610929565b9190910192915050565b6020815260008251806020840152610988816040850160208701610929565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220a1af0d6cb4f1e31496a4c5c1448913bce4bd6ad3a39e47c6f7190c114d6f9bf464736f6c63430008110033",
|
| 49 |
-
"storage": {
|
| 50 |
-
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 51 |
-
"0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 52 |
-
"0x0000000000000000000000000000000000000000000000000000000000000068": "0x00000000000000a40d5f56745a118d0906a34e69aec8c0db1cb8fa0000000100",
|
| 53 |
-
"0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0x0000000000000000000000000f99738b2fc14d77308337f3e2596b63ae7bcc4a",
|
| 54 |
-
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0x0000000000000000000000005ac4182a1dd41aeef465e40b82fd326bf66ab82c"
|
| 55 |
-
}
|
| 56 |
-
},
|
| 57 |
-
{
|
| 58 |
-
"contractName": "PolygonZkEVMGlobalExitRootL2 implementation",
|
| 59 |
-
"balance": "0",
|
| 60 |
-
"nonce": "1",
|
| 61 |
-
"address": "0x0200143Fa295EE4dffEF22eE2616c2E008D81688",
|
| 62 |
-
"bytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806301fd904414610051578063257b36321461006d57806333d6247d1461008d578063a3c573eb146100a2575b600080fd5b61005a60015481565b6040519081526020015b60405180910390f35b61005a61007b366004610162565b60006020819052908152604090205481565b6100a061009b366004610162565b6100ee565b005b6100c97f0000000000000000000000002a3dd3eb832af982ec71669e178424b10dca2ede81565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610064565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000002a3dd3eb832af982ec71669e178424b10dca2ede161461015d576040517fb49365dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600155565b60006020828403121561017457600080fd5b503591905056fea2646970667358221220a187fc278346c1b61c449ea3641002b6eac2bda3351a122a12c35099f933696864736f6c63430008110033"
|
| 63 |
-
},
|
| 64 |
-
{
|
| 65 |
-
"contractName": "PolygonZkEVMGlobalExitRootL2 proxy",
|
| 66 |
-
"balance": "0",
|
| 67 |
-
"nonce": "1",
|
| 68 |
-
"address": "0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa",
|
| 69 |
-
"bytecode": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106ca565b610118565b61005b6100933660046106e5565b61015f565b3480156100a457600080fd5b506100ad6101d0565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106ca565b61020b565b3480156100f557600080fd5b506100ad610235565b610106610292565b610116610111610331565b61033b565b565b61012061035f565b6001600160a01b0316336001600160a01b031614156101575761015481604051806020016040528060008152506000610392565b50565b6101546100fe565b61016761035f565b6001600160a01b0316336001600160a01b031614156101c8576101c38383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610392915050565b505050565b6101c36100fe565b60006101da61035f565b6001600160a01b0316336001600160a01b03161415610200576101fb610331565b905090565b6102086100fe565b90565b61021361035f565b6001600160a01b0316336001600160a01b0316141561015757610154816103f1565b600061023f61035f565b6001600160a01b0316336001600160a01b03161415610200576101fb61035f565b606061028583836040518060600160405280602781526020016107e460279139610445565b9392505050565b3b151590565b61029a61035f565b6001600160a01b0316336001600160a01b031614156101165760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b60006101fb610519565b3660008037600080366000845af43d6000803e80801561035a573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b61039b83610541565b6040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a26000825111806103dc5750805b156101c3576103eb8383610260565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61041a61035f565b604080516001600160a01b03928316815291841660208301520160405180910390a1610154816105e9565b6060833b6104a45760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610328565b600080856001600160a01b0316856040516104bf9190610794565b600060405180830381855af49150503d80600081146104fa576040519150601f19603f3d011682016040523d82523d6000602084013e6104ff565b606091505b509150915061050f828286610675565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610383565b803b6105a55760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610328565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5b80546001600160a01b0319166001600160a01b039290921691909117905550565b6001600160a01b03811661064e5760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610328565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61036105c8565b60608315610684575081610285565b8251156106945782518084602001fd5b8160405162461bcd60e51b815260040161032891906107b0565b80356001600160a01b03811681146106c557600080fd5b919050565b6000602082840312156106dc57600080fd5b610285826106ae565b6000806000604084860312156106fa57600080fd5b610703846106ae565b9250602084013567ffffffffffffffff8082111561072057600080fd5b818601915086601f83011261073457600080fd5b81358181111561074357600080fd5b87602082850101111561075557600080fd5b6020830194508093505050509250925092565b60005b8381101561078357818101518382015260200161076b565b838111156103eb5750506000910152565b600082516107a6818460208701610768565b9190910192915050565b60208152600082518060208401526107cf816040850160208701610768565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212204675187caf3a43285d9a2c1844a981e977bd52a85ff073e7fc649f73847d70a464736f6c63430008090033",
|
| 70 |
-
"storage": {
|
| 71 |
-
"0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0x0000000000000000000000000f99738b2fc14d77308337f3e2596b63ae7bcc4a",
|
| 72 |
-
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0x0000000000000000000000000200143fa295ee4dffef22ee2616c2e008d81688"
|
| 73 |
-
}
|
| 74 |
-
},
|
| 75 |
-
{
|
| 76 |
-
"contractName": "PolygonZkEVMTimelock",
|
| 77 |
-
"balance": "0",
|
| 78 |
-
"nonce": "1",
|
| 79 |
-
"address": "0xBBa0935Fa93Eb23de7990b47F0D96a8f75766d13",
|
| 80 |
-
"bytecode": "0x6080604052600436106101c65760003560e01c806364d62353116100f7578063b1c5f42711610095578063d547741f11610064578063d547741f14610661578063e38335e514610681578063f23a6e6114610694578063f27a0c92146106d957600080fd5b8063b1c5f427146105af578063bc197c81146105cf578063c4d252f514610614578063d45c44351461063457600080fd5b80638f61f4f5116100d15780638f61f4f5146104e157806391d1485414610515578063a217fddf14610566578063b08e51c01461057b57600080fd5b806364d62353146104815780638065657f146104a15780638f2a0bb0146104c157600080fd5b8063248a9ca31161016457806331d507501161013e57806331d50750146103c857806336568abe146103e85780633a6aae7214610408578063584b153e1461046157600080fd5b8063248a9ca3146103475780632ab0f529146103775780632f2ff15d146103a857600080fd5b80630d3cf6fc116101a05780630d3cf6fc1461026b578063134008d31461029f57806313bc9f20146102b2578063150b7a02146102d257600080fd5b806301d5062a146101d257806301ffc9a7146101f457806307bd02651461022957600080fd5b366101cd57005b600080fd5b3480156101de57600080fd5b506101f26101ed366004611c52565b6106ee565b005b34801561020057600080fd5b5061021461020f366004611cc7565b610783565b60405190151581526020015b60405180910390f35b34801561023557600080fd5b5061025d7fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e6381565b604051908152602001610220565b34801561027757600080fd5b5061025d7f5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca581565b6101f26102ad366004611d09565b6107df565b3480156102be57600080fd5b506102146102cd366004611d75565b6108d7565b3480156102de57600080fd5b506103166102ed366004611e9a565b7f150b7a0200000000000000000000000000000000000000000000000000000000949350505050565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610220565b34801561035357600080fd5b5061025d610362366004611d75565b60009081526020819052604090206001015490565b34801561038357600080fd5b50610214610392366004611d75565b6000908152600160208190526040909120541490565b3480156103b457600080fd5b506101f26103c3366004611f02565b6108fd565b3480156103d457600080fd5b506102146103e3366004611d75565b610927565b3480156103f457600080fd5b506101f2610403366004611f02565b610940565b34801561041457600080fd5b5061043c7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610220565b34801561046d57600080fd5b5061021461047c366004611d75565b6109f8565b34801561048d57600080fd5b506101f261049c366004611d75565b610a0e565b3480156104ad57600080fd5b5061025d6104bc366004611d09565b610ade565b3480156104cd57600080fd5b506101f26104dc366004611f73565b610b1d565b3480156104ed57600080fd5b5061025d7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc181565b34801561052157600080fd5b50610214610530366004611f02565b60009182526020828152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b34801561057257600080fd5b5061025d600081565b34801561058757600080fd5b5061025d7ffd643c72710c63c0180259aba6b2d05451e3591a24e58b62239378085726f78381565b3480156105bb57600080fd5b5061025d6105ca366004612025565b610d4f565b3480156105db57600080fd5b506103166105ea36600461214e565b7fbc197c810000000000000000000000000000000000000000000000000000000095945050505050565b34801561062057600080fd5b506101f261062f366004611d75565b610d94565b34801561064057600080fd5b5061025d61064f366004611d75565b60009081526001602052604090205490565b34801561066d57600080fd5b506101f261067c366004611f02565b610e8f565b6101f261068f366004612025565b610eb4565b3480156106a057600080fd5b506103166106af3660046121f8565b7ff23a6e610000000000000000000000000000000000000000000000000000000095945050505050565b3480156106e557600080fd5b5061025d611161565b7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc161071881611244565b6000610728898989898989610ade565b90506107348184611251565b6000817f4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca8b8b8b8b8b8a604051610770969594939291906122a6565b60405180910390a3505050505050505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e00000000000000000000000000000000000000000000000000000000014806107d957506107d98261139e565b92915050565b600080527fdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d70696020527f5ba6852781629bcdcd4bdaa6de76d786f1c64b16acdac474e55bebc0ea157951547fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e639060ff1661085c5761085c8133611435565b600061086c888888888888610ade565b905061087881856114ed565b6108848888888861162a565b6000817fc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b588a8a8a8a6040516108bc94939291906122f1565b60405180910390a36108cd8161172e565b5050505050505050565b6000818152600160205260408120546001811180156108f65750428111155b9392505050565b60008281526020819052604090206001015461091881611244565b61092283836117d7565b505050565b60008181526001602052604081205481905b1192915050565b73ffffffffffffffffffffffffffffffffffffffff811633146109ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084015b60405180910390fd5b6109f482826118c7565b5050565b6000818152600160208190526040822054610939565b333014610a9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f54696d656c6f636b436f6e74726f6c6c65723a2063616c6c6572206d7573742060448201527f62652074696d656c6f636b00000000000000000000000000000000000000000060648201526084016109e1565b60025460408051918252602082018390527f11c24f4ead16507c69ac467fbd5e4eed5fb5c699626d2cc6d66421df253886d5910160405180910390a1600255565b6000868686868686604051602001610afb969594939291906122a6565b6040516020818303038152906040528051906020012090509695505050505050565b7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc1610b4781611244565b888714610bd6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b888514610c65576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b6000610c778b8b8b8b8b8b8b8b610d4f565b9050610c838184611251565b60005b8a811015610d415780827f4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca8e8e85818110610cc357610cc3612331565b9050602002016020810190610cd89190612360565b8d8d86818110610cea57610cea612331565b905060200201358c8c87818110610d0357610d03612331565b9050602002810190610d15919061237b565b8c8b604051610d29969594939291906122a6565b60405180910390a3610d3a8161240f565b9050610c86565b505050505050505050505050565b60008888888888888888604051602001610d709897969594939291906124f7565b60405160208183030381529060405280519060200120905098975050505050505050565b7ffd643c72710c63c0180259aba6b2d05451e3591a24e58b62239378085726f783610dbe81611244565b610dc7826109f8565b610e53576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20636160448201527f6e6e6f742062652063616e63656c6c656400000000000000000000000000000060648201526084016109e1565b6000828152600160205260408082208290555183917fbaa1eb22f2a492ba1a5fea61b8df4d27c6c8b5f3971e63bb58fa14ff72eedb7091a25050565b600082815260208190526040902060010154610eaa81611244565b61092283836118c7565b600080527fdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d70696020527f5ba6852781629bcdcd4bdaa6de76d786f1c64b16acdac474e55bebc0ea157951547fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e639060ff16610f3157610f318133611435565b878614610fc0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b87841461104f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b60006110618a8a8a8a8a8a8a8a610d4f565b905061106d81856114ed565b60005b8981101561114b5760008b8b8381811061108c5761108c612331565b90506020020160208101906110a19190612360565b905060008a8a848181106110b7576110b7612331565b9050602002013590503660008a8a868181106110d5576110d5612331565b90506020028101906110e7919061237b565b915091506110f78484848461162a565b84867fc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b588686868660405161112e94939291906122f1565b60405180910390a350505050806111449061240f565b9050611070565b506111558161172e565b50505050505050505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff161580159061123257507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166315064c966040518163ffffffff1660e01b8152600401602060405180830381865afa15801561120e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123291906125be565b1561123d5750600090565b5060025490565b61124e8133611435565b50565b61125a82610927565b156112e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20616c60448201527f7265616479207363686564756c6564000000000000000000000000000000000060648201526084016109e1565b6112ef611161565b81101561137e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f54696d656c6f636b436f6e74726f6c6c65723a20696e73756666696369656e7460448201527f2064656c6179000000000000000000000000000000000000000000000000000060648201526084016109e1565b61138881426125e0565b6000928352600160205260409092209190915550565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b0000000000000000000000000000000000000000000000000000000014806107d957507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146107d9565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166109f4576114738161197e565b61147e83602061199d565b60405160200161148f929190612617565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a00000000000000000000000000000000000000000000000000000000082526109e191600401612698565b6114f6826108d7565b611582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20697360448201527f206e6f742072656164790000000000000000000000000000000000000000000060648201526084016109e1565b80158061159e5750600081815260016020819052604090912054145b6109f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f54696d656c6f636b436f6e74726f6c6c65723a206d697373696e67206465706560448201527f6e64656e6379000000000000000000000000000000000000000000000000000060648201526084016109e1565b60008473ffffffffffffffffffffffffffffffffffffffff168484846040516116549291906126e9565b60006040518083038185875af1925050503d8060008114611691576040519150601f19603f3d011682016040523d82523d6000602084013e611696565b606091505b5050905080611727576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603360248201527f54696d656c6f636b436f6e74726f6c6c65723a20756e6465726c79696e67207460448201527f72616e73616374696f6e2072657665727465640000000000000000000000000060648201526084016109e1565b5050505050565b611737816108d7565b6117c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20697360448201527f206e6f742072656164790000000000000000000000000000000000000000000060648201526084016109e1565b600090815260016020819052604090912055565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166109f45760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556118693390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16156109f45760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60606107d973ffffffffffffffffffffffffffffffffffffffff831660145b606060006119ac8360026126f9565b6119b79060026125e0565b67ffffffffffffffff8111156119cf576119cf611d8e565b6040519080825280601f01601f1916602001820160405280156119f9576020820181803683370190505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110611a3057611a30612331565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611a9357611a93612331565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000611acf8460026126f9565b611ada9060016125e0565b90505b6001811115611b77577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110611b1b57611b1b612331565b1a60f81b828281518110611b3157611b31612331565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c93611b7081612710565b9050611add565b5083156108f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016109e1565b803573ffffffffffffffffffffffffffffffffffffffff81168114611c0457600080fd5b919050565b60008083601f840112611c1b57600080fd5b50813567ffffffffffffffff811115611c3357600080fd5b602083019150836020828501011115611c4b57600080fd5b9250929050565b600080600080600080600060c0888a031215611c6d57600080fd5b611c7688611be0565b965060208801359550604088013567ffffffffffffffff811115611c9957600080fd5b611ca58a828b01611c09565b989b979a50986060810135976080820135975060a09091013595509350505050565b600060208284031215611cd957600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146108f657600080fd5b60008060008060008060a08789031215611d2257600080fd5b611d2b87611be0565b955060208701359450604087013567ffffffffffffffff811115611d4e57600080fd5b611d5a89828a01611c09565b979a9699509760608101359660809091013595509350505050565b600060208284031215611d8757600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611e0457611e04611d8e565b604052919050565b600082601f830112611e1d57600080fd5b813567ffffffffffffffff811115611e3757611e37611d8e565b611e6860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611dbd565b818152846020838601011115611e7d57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215611eb057600080fd5b611eb985611be0565b9350611ec760208601611be0565b925060408501359150606085013567ffffffffffffffff811115611eea57600080fd5b611ef687828801611e0c565b91505092959194509250565b60008060408385031215611f1557600080fd5b82359150611f2560208401611be0565b90509250929050565b60008083601f840112611f4057600080fd5b50813567ffffffffffffffff811115611f5857600080fd5b6020830191508360208260051b8501011115611c4b57600080fd5b600080600080600080600080600060c08a8c031215611f9157600080fd5b893567ffffffffffffffff80821115611fa957600080fd5b611fb58d838e01611f2e565b909b50995060208c0135915080821115611fce57600080fd5b611fda8d838e01611f2e565b909950975060408c0135915080821115611ff357600080fd5b506120008c828d01611f2e565b9a9d999c50979a969997986060880135976080810135975060a0013595509350505050565b60008060008060008060008060a0898b03121561204157600080fd5b883567ffffffffffffffff8082111561205957600080fd5b6120658c838d01611f2e565b909a50985060208b013591508082111561207e57600080fd5b61208a8c838d01611f2e565b909850965060408b01359150808211156120a357600080fd5b506120b08b828c01611f2e565b999c989b509699959896976060870135966080013595509350505050565b600082601f8301126120df57600080fd5b8135602067ffffffffffffffff8211156120fb576120fb611d8e565b8160051b61210a828201611dbd565b928352848101820192828101908785111561212457600080fd5b83870192505b848310156121435782358252918301919083019061212a565b979650505050505050565b600080600080600060a0868803121561216657600080fd5b61216f86611be0565b945061217d60208701611be0565b9350604086013567ffffffffffffffff8082111561219a57600080fd5b6121a689838a016120ce565b945060608801359150808211156121bc57600080fd5b6121c889838a016120ce565b935060808801359150808211156121de57600080fd5b506121eb88828901611e0c565b9150509295509295909350565b600080600080600060a0868803121561221057600080fd5b61221986611be0565b945061222760208701611be0565b93506040860135925060608601359150608086013567ffffffffffffffff81111561225157600080fd5b6121eb88828901611e0c565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff8716815285602082015260a0604082015260006122dc60a08301868861225d565b60608301949094525060800152949350505050565b73ffffffffffffffffffffffffffffffffffffffff8516815283602082015260606040820152600061232760608301848661225d565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561237257600080fd5b6108f682611be0565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126123b057600080fd5b83018035915067ffffffffffffffff8211156123cb57600080fd5b602001915036819003821315611c4b57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612440576124406123e0565b5060010190565b81835260006020808501808196508560051b810191508460005b878110156124ea57828403895281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18836030181126124a057600080fd5b8701858101903567ffffffffffffffff8111156124bc57600080fd5b8036038213156124cb57600080fd5b6124d686828461225d565b9a87019a9550505090840190600101612461565b5091979650505050505050565b60a0808252810188905260008960c08301825b8b8110156125455773ffffffffffffffffffffffffffffffffffffffff61253084611be0565b1682526020928301929091019060010161250a565b5083810360208501528881527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff89111561257e57600080fd5b8860051b9150818a602083013701828103602090810160408501526125a69082018789612447565b60608401959095525050608001529695505050505050565b6000602082840312156125d057600080fd5b815180151581146108f657600080fd5b808201808211156107d9576107d96123e0565b60005b8381101561260e5781810151838201526020016125f6565b50506000910152565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161264f8160178501602088016125f3565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000601791840191820152835161268c8160288401602088016125f3565b01602801949350505050565b60208152600082518060208401526126b78160408501602087016125f3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b8183823760009101908152919050565b80820281158282048414176107d9576107d96123e0565b60008161271f5761271f6123e0565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea26469706673582212206416c4e08f97752b4bb06159524dac058d3dccd8775e57ef1b01505751ebf7af64736f6c63430008110033",
|
| 81 |
-
"storage": {
|
| 82 |
-
"0x0000000000000000000000000000000000000000000000000000000000000002": "0x00000000000000000000000000000000000000000000000000000000000d2f00",
|
| 83 |
-
"0x33d4aa03df3f12c4f615b40676f67fdafecd3edb5a9c0ca2a47a923dae33a023": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 84 |
-
"0x9fa2d8034dbcb437bee38d61fbd100910e1342ffc07f128aa1b8e6790b7f3f68": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 85 |
-
"0x64494413541ff93b31aa309254e3fed72a7456e9845988b915b4c7a7ceba8814": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5",
|
| 86 |
-
"0x531a7c25761aa4b0f2310edca9bb25e1e3ceb49ad4b0422aec866b3ce7567c87": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 87 |
-
"0x3412d5605ac6cd444957cedb533e5dacad6378b4bc819ebe3652188a665066d6": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5",
|
| 88 |
-
"0xedbedc78c4240c7613622a35de050b48bd6c6d9a31b3d485b68fbbed54a4802d": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 89 |
-
"0xdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d706a": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5",
|
| 90 |
-
"0x76616448da8d124a07383c26a6b2433b3259de946aa40f51524ec96ee05e871a": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 91 |
-
"0xc3ad33e20b0c56a223ad5104fff154aa010f8715b9c981fd38fdc60a4d1a52fc": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5"
|
| 92 |
-
}
|
| 93 |
-
},
|
| 94 |
-
{
|
| 95 |
-
"accountName": "keyless Deployer",
|
| 96 |
-
"balance": "0",
|
| 97 |
-
"nonce": "1",
|
| 98 |
-
"address": "0x9d90066e7478496e2284E54c3548106bb4F90E50"
|
| 99 |
-
},
|
| 100 |
-
{
|
| 101 |
-
"accountName": "deployer",
|
| 102 |
-
"balance": "0",
|
| 103 |
-
"nonce": "8",
|
| 104 |
-
"address": "0x4c1665d6651ecEfa59B9B3041951608468b18891"
|
| 105 |
-
}
|
| 106 |
-
]
|
| 107 |
-
}
|
| 108 |
-
`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -25,17 +25,16 @@
|
|
| 25 |
|
| 26 |
type network string
|
| 27 |
|
| 28 |
-
const mainnet network = "mainnet"
|
| 29 |
-
const testnet network = "testnet"
|
| 30 |
-
const cardona network = "cardona"
|
| 31 |
const custom network = "custom"
|
| 32 |
|
| 33 |
// GenesisFromJSON is the config file for network_custom
|
| 34 |
type GenesisFromJSON struct {
|
| 35 |
// L1: root hash of the genesis block
|
| 36 |
Root string `json:"root"`
|
| 37 |
-
// L1: block number
|
| 38 |
-
|
|
|
|
|
|
|
| 39 |
// L2: List of states contracts used to populate merkle tree at initial state
|
| 40 |
Genesis []genesisAccountFromJSON `json:"genesis"`
|
| 41 |
// L1: configuration of the network
|
|
@@ -60,12 +59,6 @@
|
|
| 60 |
func (cfg *Config) loadNetworkConfig(ctx *cli.Context) {
|
| 61 |
var networkJSON string
|
| 62 |
switch ctx.String(FlagNetwork) {
|
| 63 |
-
case string(mainnet):
|
| 64 |
-
networkJSON = MainnetNetworkConfigJSON
|
| 65 |
-
case string(testnet):
|
| 66 |
-
networkJSON = TestnetNetworkConfigJSON
|
| 67 |
-
case string(cardona):
|
| 68 |
-
networkJSON = CardonaNetworkConfigJSON
|
| 69 |
case string(custom):
|
| 70 |
var err error
|
| 71 |
cfgPath := ctx.String(FlagCustomNetwork)
|
|
@@ -74,7 +67,7 @@
|
|
| 74 |
panic(err.Error())
|
| 75 |
}
|
| 76 |
default:
|
| 77 |
-
log.Fatalf("unsupported --network value. Must be
|
| 78 |
}
|
| 79 |
config, err := LoadGenesisFromJSONString(networkJSON)
|
| 80 |
if err != nil {
|
|
@@ -122,9 +115,10 @@
|
|
| 122 |
|
| 123 |
cfg.L1Config = cfgJSON.L1Config
|
| 124 |
cfg.Genesis = state.Genesis{
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
|
|
|
| 128 |
}
|
| 129 |
|
| 130 |
for _, account := range cfgJSON.Genesis {
|
|
|
|
| 25 |
|
| 26 |
type network string
|
| 27 |
|
|
|
|
|
|
|
|
|
|
| 28 |
const custom network = "custom"
|
| 29 |
|
| 30 |
// GenesisFromJSON is the config file for network_custom
|
| 31 |
type GenesisFromJSON struct {
|
| 32 |
// L1: root hash of the genesis block
|
| 33 |
Root string `json:"root"`
|
| 34 |
+
// L1: block number in which the rollup was created
|
| 35 |
+
RollupCreationBlockNum uint64 `json:"rollupCreationBlockNumber"`
|
| 36 |
+
// L1: block number in which the rollup manager was created
|
| 37 |
+
RollupManagerCreationBlockNum uint64 `json:"rollupManagerCreationBlockNumber"`
|
| 38 |
// L2: List of states contracts used to populate merkle tree at initial state
|
| 39 |
Genesis []genesisAccountFromJSON `json:"genesis"`
|
| 40 |
// L1: configuration of the network
|
|
|
|
| 59 |
func (cfg *Config) loadNetworkConfig(ctx *cli.Context) {
|
| 60 |
var networkJSON string
|
| 61 |
switch ctx.String(FlagNetwork) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
case string(custom):
|
| 63 |
var err error
|
| 64 |
cfgPath := ctx.String(FlagCustomNetwork)
|
|
|
|
| 67 |
panic(err.Error())
|
| 68 |
}
|
| 69 |
default:
|
| 70 |
+
log.Fatalf("unsupported --network value. Must be %s", custom)
|
| 71 |
}
|
| 72 |
config, err := LoadGenesisFromJSONString(networkJSON)
|
| 73 |
if err != nil {
|
|
|
|
| 115 |
|
| 116 |
cfg.L1Config = cfgJSON.L1Config
|
| 117 |
cfg.Genesis = state.Genesis{
|
| 118 |
+
RollupBlockNumber: cfgJSON.RollupCreationBlockNum,
|
| 119 |
+
RollupManagerBlockNumber: cfgJSON.RollupManagerCreationBlockNum,
|
| 120 |
+
Root: common.HexToHash(cfgJSON.Root),
|
| 121 |
+
Actions: []*state.GenesisAction{},
|
| 122 |
}
|
| 123 |
|
| 124 |
for _, account := range cfgJSON.Genesis {
|
|
@@ -14,18 +13,6 @@
|
|
| 14 |
"github.com/urfave/cli/v2"
|
| 15 |
)
|
| 16 |
|
| 17 |
-
func TestCardona(t *testing.T) {
|
| 18 |
-
cfg := Config{}
|
| 19 |
-
fs := flag.NewFlagSet("", flag.ExitOnError)
|
| 20 |
-
fs.String(FlagNetwork, string(cardona), string(cardona))
|
| 21 |
-
err := fs.Set(FlagNetwork, string(cardona))
|
| 22 |
-
require.NoError(t, err)
|
| 23 |
-
app := cli.NewApp()
|
| 24 |
-
ctx := cli.NewContext(app, fs, nil)
|
| 25 |
-
|
| 26 |
-
log.Info("flag=", ctx.String(FlagNetwork))
|
| 27 |
-
cfg.loadNetworkConfig(ctx)
|
| 28 |
-
}
|
| 29 |
func TestLoadCustomNetworkConfig(t *testing.T) {
|
| 30 |
tcs := []struct {
|
| 31 |
description string
|
|
@@ -37,7 +24,8 @@
|
|
| 37 |
description: "happy path",
|
| 38 |
inputConfigStr: `{
|
| 39 |
"root": "0xBEEF",
|
| 40 |
-
"
|
|
|
|
| 41 |
"l1Config" : {
|
| 42 |
"chainId": 420,
|
| 43 |
"polygonZkEVMAddress": "0xc949254d682d8c9ad5682521675b8f43b102aec4",
|
|
@@ -89,8 +77,9 @@
|
|
| 89 |
GlobalExitRootManagerAddr: common.HexToAddress("0xc949254d682d8c9ad5682521675b8f43b102aec4"),
|
| 90 |
},
|
| 91 |
Genesis: state.Genesis{
|
| 92 |
-
Root:
|
| 93 |
-
|
|
|
|
| 94 |
Actions: []*state.GenesisAction{
|
| 95 |
{
|
| 96 |
Address: "0xc949254d682d8c9ad5682521675b8f43b102aec4",
|
|
|
|
| 13 |
"github.com/urfave/cli/v2"
|
| 14 |
)
|
| 15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
func TestLoadCustomNetworkConfig(t *testing.T) {
|
| 17 |
tcs := []struct {
|
| 18 |
description string
|
|
|
|
| 24 |
description: "happy path",
|
| 25 |
inputConfigStr: `{
|
| 26 |
"root": "0xBEEF",
|
| 27 |
+
"rollupCreationBlockNumber": 69,
|
| 28 |
+
"rollupManagerCreationBlockNumber": 60,
|
| 29 |
"l1Config" : {
|
| 30 |
"chainId": 420,
|
| 31 |
"polygonZkEVMAddress": "0xc949254d682d8c9ad5682521675b8f43b102aec4",
|
|
|
|
| 77 |
GlobalExitRootManagerAddr: common.HexToAddress("0xc949254d682d8c9ad5682521675b8f43b102aec4"),
|
| 78 |
},
|
| 79 |
Genesis: state.Genesis{
|
| 80 |
+
Root: common.HexToHash("0xBEEF"),
|
| 81 |
+
RollupBlockNumber: 69,
|
| 82 |
+
RollupManagerBlockNumber: 60,
|
| 83 |
Actions: []*state.GenesisAction{
|
| 84 |
{
|
| 85 |
Address: "0xc949254d682d8c9ad5682521675b8f43b102aec4",
|
|
@@ -1,108 +0,0 @@
|
|
| 1 |
-
package config
|
| 2 |
-
|
| 3 |
-
// TestnetNetworkConfigJSON is the hardcoded network configuration to be used for the official mainnet setup
|
| 4 |
-
const TestnetNetworkConfigJSON = `
|
| 5 |
-
{
|
| 6 |
-
"l1Config" : {
|
| 7 |
-
"chainId": 5,
|
| 8 |
-
"polygonZkEVMAddress": "0xa997cfD539E703921fD1e3Cf25b4c241a27a4c7A",
|
| 9 |
-
"polTokenAddress": "0x1319D23c2F7034F52Eb07399702B040bA278Ca49",
|
| 10 |
-
"polygonZkEVMGlobalExitRootAddress": "0x4d9427DCA0406358445bC0a8F88C26b704004f74"
|
| 11 |
-
},
|
| 12 |
-
"root": "0x13a14c4a8288e782863d7ce916d224546c69dc428fbfa7115a0cc33a27a05b26",
|
| 13 |
-
"genesisBlockNumber": 8572998,
|
| 14 |
-
"genesis": [
|
| 15 |
-
{
|
| 16 |
-
"contractName": "PolygonZkEVMDeployer",
|
| 17 |
-
"balance": "0",
|
| 18 |
-
"nonce": "4",
|
| 19 |
-
"address": "0x39877a0c3cd148476DaA2475c77c478C62eC7509",
|
| 20 |
-
"bytecode": "0x6080604052600436106100705760003560e01c8063715018a61161004e578063715018a6146100e65780638da5cb5b146100fb578063e11ae6cb14610126578063f2fde38b1461013957600080fd5b80632b79805a146100755780634a94d4871461008a5780636d07dbf81461009d575b600080fd5b610088610083366004610927565b610159565b005b6100886100983660046109c7565b6101cb565b3480156100a957600080fd5b506100bd6100b8366004610a1e565b61020d565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b50610088610220565b34801561010757600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166100bd565b610088610134366004610a40565b610234565b34801561014557600080fd5b50610088610154366004610a90565b61029b565b610161610357565b600061016e8585856103d8565b905061017a8183610537565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527fba82f25fed02cd2a23d9f5d11c2ef588d22af5437cbf23bfe61d87257c480e4c9060200160405180910390a15050505050565b6101d3610357565b6101de83838361057b565b506040517f25adb19089b6a549831a273acdf7908cff8b7ee5f551f8d1d37996cf01c5df5b90600090a1505050565b600061021983836105a9565b9392505050565b610228610357565b61023260006105b6565b565b61023c610357565b60006102498484846103d8565b60405173ffffffffffffffffffffffffffffffffffffffff821681529091507fba82f25fed02cd2a23d9f5d11c2ef588d22af5437cbf23bfe61d87257c480e4c9060200160405180910390a150505050565b6102a3610357565b73ffffffffffffffffffffffffffffffffffffffff811661034b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610354816105b6565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610232576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610342565b600083471015610444576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e63650000006044820152606401610342565b81516000036104af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f6044820152606401610342565b8282516020840186f5905073ffffffffffffffffffffffffffffffffffffffff8116610219576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f79000000000000006044820152606401610342565b6060610219838360006040518060400160405280601e81526020017f416464726573733a206c6f772d6c6576656c2063616c6c206661696c6564000081525061062b565b60606105a1848484604051806060016040528060298152602001610b3d6029913961062b565b949350505050565b6000610219838330610744565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060824710156106bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610342565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516106e69190610acf565b60006040518083038185875af1925050503d8060008114610723576040519150601f19603f3d011682016040523d82523d6000602084013e610728565b606091505b50915091506107398783838761076e565b979650505050505050565b6000604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b606083156108045782516000036107fd5773ffffffffffffffffffffffffffffffffffffffff85163b6107fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610342565b50816105a1565b6105a183838151156108195781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103429190610aeb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261088d57600080fd5b813567ffffffffffffffff808211156108a8576108a861084d565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156108ee576108ee61084d565b8160405283815286602085880101111561090757600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000806080858703121561093d57600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561096357600080fd5b61096f8883890161087c565b9350606087013591508082111561098557600080fd5b506109928782880161087c565b91505092959194509250565b803573ffffffffffffffffffffffffffffffffffffffff811681146109c257600080fd5b919050565b6000806000606084860312156109dc57600080fd5b6109e58461099e565b9250602084013567ffffffffffffffff811115610a0157600080fd5b610a0d8682870161087c565b925050604084013590509250925092565b60008060408385031215610a3157600080fd5b50508035926020909101359150565b600080600060608486031215610a5557600080fd5b8335925060208401359150604084013567ffffffffffffffff811115610a7a57600080fd5b610a868682870161087c565b9150509250925092565b600060208284031215610aa257600080fd5b6102198261099e565b60005b83811015610ac6578181015183820152602001610aae565b50506000910152565b60008251610ae1818460208701610aab565b9190910192915050565b6020815260008251806020840152610b0a816040850160208701610aab565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2063616c6c20776974682076616c7565206661696c6564a26469706673582212200b8e3cd6bd762444a7eeff86e1cfcd7e1ce9524b715dcb70b2a4c2b70fd5188464736f6c63430008110033",
|
| 21 |
-
"storage": {
|
| 22 |
-
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000a0b02b28920812324f1cc3255bd8840867d3f227"
|
| 23 |
-
}
|
| 24 |
-
},
|
| 25 |
-
{
|
| 26 |
-
"contractName": "ProxyAdmin",
|
| 27 |
-
"balance": "0",
|
| 28 |
-
"nonce": "1",
|
| 29 |
-
"address": "0x40797c2f93298a44a893F43EdF1B33B63d7BA333",
|
| 30 |
-
"bytecode": "0x60806040526004361061007b5760003560e01c80639623609d1161004e5780639623609d1461012b57806399a88ec41461013e578063f2fde38b1461015e578063f3b7dead1461017e57600080fd5b8063204e1c7a14610080578063715018a6146100c95780637eff275e146100e05780638da5cb5b14610100575b600080fd5b34801561008c57600080fd5b506100a061009b366004610608565b61019e565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100d557600080fd5b506100de610255565b005b3480156100ec57600080fd5b506100de6100fb36600461062c565b610269565b34801561010c57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166100a0565b6100de610139366004610694565b6102f7565b34801561014a57600080fd5b506100de61015936600461062c565b61038c565b34801561016a57600080fd5b506100de610179366004610608565b6103e8565b34801561018a57600080fd5b506100a0610199366004610608565b6104a4565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907f5c60da1b00000000000000000000000000000000000000000000000000000000815260040190565b600060405180830381855afa9150503d8060008114610225576040519150601f19603f3d011682016040523d82523d6000602084013e61022a565b606091505b50915091508161023957600080fd5b8080602001905181019061024d9190610788565b949350505050565b61025d6104f0565b6102676000610571565b565b6102716104f0565b6040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690638f283970906024015b600060405180830381600087803b1580156102db57600080fd5b505af11580156102ef573d6000803e3d6000fd5b505050505050565b6102ff6104f0565b6040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690634f1ef28690349061035590869086906004016107a5565b6000604051808303818588803b15801561036e57600080fd5b505af1158015610382573d6000803e3d6000fd5b5050505050505050565b6103946104f0565b6040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690633659cfe6906024016102c1565b6103f06104f0565b73ffffffffffffffffffffffffffffffffffffffff8116610498576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6104a181610571565b50565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907ff851a44000000000000000000000000000000000000000000000000000000000815260040190565b60005473ffffffffffffffffffffffffffffffffffffffff163314610267576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161048f565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff811681146104a157600080fd5b60006020828403121561061a57600080fd5b8135610625816105e6565b9392505050565b6000806040838503121561063f57600080fd5b823561064a816105e6565b9150602083013561065a816105e6565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000606084860312156106a957600080fd5b83356106b4816105e6565b925060208401356106c4816105e6565b9150604084013567ffffffffffffffff808211156106e157600080fd5b818601915086601f8301126106f557600080fd5b81358181111561070757610707610665565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561074d5761074d610665565b8160405282815289602084870101111561076657600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b60006020828403121561079a57600080fd5b8151610625816105e6565b73ffffffffffffffffffffffffffffffffffffffff8316815260006020604081840152835180604085015260005b818110156107ef578581018301518582016060015282016107d3565b5060006060828601015260607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010192505050939250505056fea2646970667358221220babd4ff1f5daee002b96cc86d8bb6c2c2c210ae3132df5ea384713352f7f15fe64736f6c63430008110033",
|
| 31 |
-
"storage": {
|
| 32 |
-
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x00000000000000000000000002245d7b6cb0b6870d1e28ac877ee355b9588869"
|
| 33 |
-
}
|
| 34 |
-
},
|
| 35 |
-
{
|
| 36 |
-
"contractName": "PolygonZkEVMBridge implementation",
|
| 37 |
-
"balance": "0",
|
| 38 |
-
"nonce": "1",
|
| 39 |
-
"address": "0x39e780D8800f7396e8B7530A8925B14025AedC77",
|
| 40 |
-
"bytecode": "0x6080604052600436106200019f5760003560e01c8063647c576c11620000e7578063be5831c71162000089578063dbc169761162000060578063dbc169761462000639578063ee25560b1462000651578063fb570834146200068257600080fd5b8063be5831c714620005ae578063cd58657914620005ea578063d02103ca146200060157600080fd5b80639e34070f11620000be5780639e34070f146200050a578063aaa13cc2146200054f578063bab161bf146200057457600080fd5b8063647c576c146200048657806379e2cf9714620004ab57806381b1c17414620004c357600080fd5b80632d2c9d94116200015157806334ac9cf2116200012857806334ac9cf2146200034b5780633ae05047146200037a5780633e197043146200039257600080fd5b80632d2c9d9414620002765780632dfdf0b5146200029b578063318aee3d14620002c257600080fd5b806322e95f2c116200018657806322e95f2c14620001ef578063240ff378146200023a5780632cffd02e146200025157600080fd5b806315064c9614620001a45780632072f6c514620001d5575b600080fd5b348015620001b157600080fd5b50606854620001c09060ff1681565b60405190151581526020015b60405180910390f35b348015620001e257600080fd5b50620001ed620006a7565b005b348015620001fc57600080fd5b50620002146200020e366004620032db565b62000705565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001620001cc565b620001ed6200024b36600462003372565b620007a8565b3480156200025e57600080fd5b50620001ed6200027036600462003409565b620009d0565b3480156200028357600080fd5b50620001ed6200029536600462003409565b62000f74565b348015620002a857600080fd5b50620002b360535481565b604051908152602001620001cc565b348015620002cf57600080fd5b5062000319620002e1366004620034ef565b606b6020526000908152604090205463ffffffff811690640100000000900473ffffffffffffffffffffffffffffffffffffffff1682565b6040805163ffffffff909316835273ffffffffffffffffffffffffffffffffffffffff909116602083015201620001cc565b3480156200035857600080fd5b50606c54620002149073ffffffffffffffffffffffffffffffffffffffff1681565b3480156200038757600080fd5b50620002b362001178565b3480156200039f57600080fd5b50620002b3620003b136600462003526565b6040517fff0000000000000000000000000000000000000000000000000000000000000060f889901b1660208201527fffffffff0000000000000000000000000000000000000000000000000000000060e088811b821660218401527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606089811b821660258601529188901b909216603984015285901b16603d8201526051810183905260718101829052600090609101604051602081830303815290604052805190602001209050979650505050505050565b3480156200049357600080fd5b50620001ed620004a5366004620035b0565b6200125e565b348015620004b857600080fd5b50620001ed620014ad565b348015620004d057600080fd5b5062000214620004e236600462003600565b606a6020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b3480156200051757600080fd5b50620001c06200052936600462003600565b600881901c600090815260696020526040902054600160ff9092169190911b9081161490565b3480156200055c57600080fd5b50620002146200056e3660046200361a565b620014e7565b3480156200058157600080fd5b506068546200059890610100900463ffffffff1681565b60405163ffffffff9091168152602001620001cc565b348015620005bb57600080fd5b506068546200059890790100000000000000000000000000000000000000000000000000900463ffffffff1681565b620001ed620005fb366004620036ce565b620016d3565b3480156200060e57600080fd5b50606854620002149065010000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156200064657600080fd5b50620001ed62001c37565b3480156200065e57600080fd5b50620002b36200067036600462003600565b60696020526000908152604090205481565b3480156200068f57600080fd5b50620001c0620006a136600462003770565b62001c93565b606c5473ffffffffffffffffffffffffffffffffffffffff163314620006f9576040517fe2e8106b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6200070362001d7c565b565b6040805160e084901b7fffffffff0000000000000000000000000000000000000000000000000000000016602080830191909152606084901b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602483015282516018818403018152603890920183528151918101919091206000908152606a909152205473ffffffffffffffffffffffffffffffffffffffff165b92915050565b60685460ff1615620007e6576040517f2f0047fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60685463ffffffff8681166101009092041614806200080c5750600263ffffffff861610155b1562000844576040517f0595ea2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b6001606860019054906101000a900463ffffffff163388883488886053546040516200089a9998979695949392919062003806565b60405180910390a1620009b8620009b26001606860019054906101000a900463ffffffff16338989348989604051620008d592919062003881565b60405180910390206040517fff0000000000000000000000000000000000000000000000000000000000000060f889901b1660208201527fffffffff0000000000000000000000000000000000000000000000000000000060e088811b821660218401527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606089811b821660258601529188901b909216603984015285901b16603d8201526051810183905260718101829052600090609101604051602081830303815290604052805190602001209050979650505050505050565b62001e10565b8215620009c957620009c962001f27565b5050505050565b60685460ff161562000a0e576040517f2f0047fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62000a258b8b8b8b8b8b8b8b8b8b8b600062001ffc565b73ffffffffffffffffffffffffffffffffffffffff861662000b01576040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff861690859060405162000a7a9190620038e6565b60006040518083038185875af1925050503d806000811462000ab9576040519150601f19603f3d011682016040523d82523d6000602084013e62000abe565b606091505b505090508062000afa576040517f6747a28800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5062000efc565b60685463ffffffff61010090910481169088160362000b435762000b3d73ffffffffffffffffffffffffffffffffffffffff87168585620021ed565b62000efc565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e089901b1660208201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b166024820152600090603801604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152606a90935291205490915073ffffffffffffffffffffffffffffffffffffffff168062000e6e576000808062000c1886880188620039fb565b92509250925060008584848460405162000c329062003292565b62000c409392919062003abd565b8190604051809103906000f590508015801562000c61573d6000803e3d6000fd5b506040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8c81166004830152602482018c9052919250908216906340c10f1990604401600060405180830381600087803b15801562000cd757600080fd5b505af115801562000cec573d6000803e3d6000fd5b5050505080606a600088815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060405180604001604052808e63ffffffff1681526020018d73ffffffffffffffffffffffffffffffffffffffff16815250606b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050507f490e59a1701b938786ac72570a1efeac994a3dbe96e2e883e19e902ace6e6a398d8d838b8b60405162000e5c95949392919062003afa565b60405180910390a15050505062000ef9565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8781166004830152602482018790528216906340c10f1990604401600060405180830381600087803b15801562000edf57600080fd5b505af115801562000ef4573d6000803e3d6000fd5b505050505b50505b6040805163ffffffff8c811682528916602082015273ffffffffffffffffffffffffffffffffffffffff88811682840152861660608201526080810185905290517f25308c93ceeed162da955b3f7ce3e3f93606579e40fb92029faa9efe275459839181900360a00190a15050505050505050505050565b60685460ff161562000fb2576040517f2f0047fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62000fc98b8b8b8b8b8b8b8b8b8b8b600162001ffc565b60008473ffffffffffffffffffffffffffffffffffffffff1684888a868660405160240162000ffc949392919062003b42565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1806b5f200000000000000000000000000000000000000000000000000000000179052516200107f9190620038e6565b60006040518083038185875af1925050503d8060008114620010be576040519150601f19603f3d011682016040523d82523d6000602084013e620010c3565b606091505b5050905080620010ff576040517f37e391c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805163ffffffff8d811682528a16602082015273ffffffffffffffffffffffffffffffffffffffff89811682840152871660608201526080810186905290517f25308c93ceeed162da955b3f7ce3e3f93606579e40fb92029faa9efe275459839181900360a00190a1505050505050505050505050565b605354600090819081805b602081101562001255578083901c600116600103620011e65760338160208110620011b257620011b262003b8a565b0154604080516020810192909252810185905260600160405160208183030381529060405280519060200120935062001213565b60408051602081018690529081018390526060016040516020818303038152906040528051906020012093505b604080516020810184905290810183905260600160405160208183030381529060405280519060200120915080806200124c9062003be8565b91505062001183565b50919392505050565b600054610100900460ff16158080156200127f5750600054600160ff909116105b806200129b5750303b1580156200129b575060005460ff166001145b6200132d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156200138c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b606880547fffffffffffffff000000000000000000000000000000000000000000000000ff1661010063ffffffff8716027fffffffffffffff0000000000000000000000000000000000000000ffffffffff16176501000000000073ffffffffffffffffffffffffffffffffffffffff8681169190910291909117909155606c80547fffffffffffffffffffffffff00000000000000000000000000000000000000001691841691909117905562001443620022c3565b8015620014a757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b605354606854790100000000000000000000000000000000000000000000000000900463ffffffff16101562000703576200070362001f27565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e089901b1660208201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b1660248201526000908190603801604051602081830303815290604052805190602001209050600060ff60f81b3083604051806020016200157d9062003292565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f909101166040819052620015c8908d908d908d908d908d9060200162003c23565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905262001606929160200162003c64565b604051602081830303815290604052805190602001206040516020016200168f94939291907fff0000000000000000000000000000000000000000000000000000000000000094909416845260609290921b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660018401526015830152603582015260550190565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101209a9950505050505050505050565b60685460ff161562001711576040517f2f0047fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6200171b62002366565b60685463ffffffff888116610100909204161480620017415750600263ffffffff881610155b1562001779576040517f0595ea2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060608773ffffffffffffffffffffffffffffffffffffffff8816620017df57883414620017d5576040517fb89240f500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000925062001ad9565b341562001818576040517f798ee6f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8089166000908152606b602090815260409182902082518084019093525463ffffffff811683526401000000009004909216918101829052901562001908576040517f9dc29fac000000000000000000000000000000000000000000000000000000008152336004820152602481018b905273ffffffffffffffffffffffffffffffffffffffff8a1690639dc29fac90604401600060405180830381600087803b158015620018db57600080fd5b505af1158015620018f0573d6000803e3d6000fd5b50505050806020015194508060000151935062001ad7565b85156200191d576200191d898b8989620023db565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8b16906370a0823190602401602060405180830381865afa1580156200198b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620019b1919062003c97565b9050620019d773ffffffffffffffffffffffffffffffffffffffff8b1633308e620028f9565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8c16906370a0823190602401602060405180830381865afa15801562001a45573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001a6b919062003c97565b905062001a79828262003cb1565b6068548c9850610100900463ffffffff169650935062001a998762002959565b62001aa48c62002a71565b62001aaf8d62002b7e565b60405160200162001ac39392919062003abd565b604051602081830303815290604052945050505b505b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b600084868e8e868860535460405162001b1b98979695949392919062003cc7565b60405180910390a162001c0f620009b2600085878f8f8789805190602001206040517fff0000000000000000000000000000000000000000000000000000000000000060f889901b1660208201527fffffffff0000000000000000000000000000000000000000000000000000000060e088811b821660218401527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606089811b821660258601529188901b909216603984015285901b16603d8201526051810183905260718101829052600090609101604051602081830303815290604052805190602001209050979650505050505050565b861562001c205762001c2062001f27565b5050505062001c2e60018055565b50505050505050565b606c5473ffffffffffffffffffffffffffffffffffffffff16331462001c89576040517fe2e8106b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6200070362002c80565b600084815b602081101562001d6e57600163ffffffff8616821c8116900362001d0a5785816020811062001ccb5762001ccb62003b8a565b60200201358260405160200162001cec929190918252602082015260400190565b60405160208183030381529060405280519060200120915062001d59565b8186826020811062001d205762001d2062003b8a565b602002013560405160200162001d40929190918252602082015260400190565b6040516020818303038152906040528051906020012091505b8062001d658162003be8565b91505062001c98565b50821490505b949350505050565b60685460ff161562001dba576040517f2f0047fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040517f2261efe5aef6fedc1fd1550b25facc9181745623049c7901287030b9ad1a549790600090a1565b80600162001e216020600262003e79565b62001e2d919062003cb1565b6053541062001e68576040517fef5ccf6600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060536000815462001e7b9062003be8565b9182905550905060005b602081101562001f17578082901c60011660010362001ebd57826033826020811062001eb55762001eb562003b8a565b015550505050565b6033816020811062001ed35762001ed362003b8a565b01546040805160208101929092528101849052606001604051602081830303815290604052805190602001209250808062001f0e9062003be8565b91505062001e85565b5062001f2262003e87565b505050565b6053546068805463ffffffff909216790100000000000000000000000000000000000000000000000000027fffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffffff909216919091179081905573ffffffffffffffffffffffffffffffffffffffff65010000000000909104166333d6247d62001fad62001178565b6040518263ffffffff1660e01b815260040162001fcc91815260200190565b600060405180830381600087803b15801562001fe757600080fd5b505af1158015620014a7573d6000803e3d6000fd5b6200200d8b63ffffffff1662002d10565b6068546040805160208082018e90528183018d9052825180830384018152606083019384905280519101207f257b363200000000000000000000000000000000000000000000000000000000909252606481019190915260009165010000000000900473ffffffffffffffffffffffffffffffffffffffff169063257b3632906084016020604051808303816000875af1158015620020b0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620020d6919062003c97565b90508060000362002112576040517e2f6fad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60685463ffffffff88811661010090920416146200215c576040517f0595ea2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606854600090610100900463ffffffff166200217a5750896200217d565b508a5b620021a66200219d848c8c8c8c8c8c8c604051620008d592919062003881565b8f8f8462001c93565b620021dd576040517fe0417cec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905262001f229084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915262002d75565b600054610100900460ff166200235c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162001324565b6200070362002e88565b600260015403620023d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640162001324565b6002600155565b6000620023ec600482848662003eb6565b620023f79162003ee2565b90507f2afa5331000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000821601620026765760008080808080806200245a896004818d62003eb6565b81019062002469919062003f2b565b96509650965096509650965096503373ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614620024dd576040517f912ecce700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff861630146200252d576040517f750643af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8a851462002567576040517f03fffc4b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805173ffffffffffffffffffffffffffffffffffffffff89811660248301528881166044830152606482018890526084820187905260ff861660a483015260c4820185905260e48083018590528351808403909101815261010490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd505accf000000000000000000000000000000000000000000000000000000001790529151918e1691620026229190620038e6565b6000604051808303816000865af19150503d806000811462002661576040519150601f19603f3d011682016040523d82523d6000602084013e62002666565b606091505b50505050505050505050620009c9565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f8fcbaf0c0000000000000000000000000000000000000000000000000000000014620026f2576040517fe282c0ba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808080808080806200270a8a6004818e62003eb6565b81019062002719919062003f86565b975097509750975097509750975097503373ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff16146200278f576040517f912ecce700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87163014620027df576040517f750643af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805173ffffffffffffffffffffffffffffffffffffffff8a811660248301528981166044830152606482018990526084820188905286151560a483015260ff861660c483015260e482018590526101048083018590528351808403909101815261012490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f8fcbaf0c000000000000000000000000000000000000000000000000000000001790529151918f1691620028a39190620038e6565b6000604051808303816000865af19150503d8060008114620028e2576040519150601f19603f3d011682016040523d82523d6000602084013e620028e7565b606091505b50505050505050505050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052620014a79085907f23b872dd000000000000000000000000000000000000000000000000000000009060840162002240565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f06fdde03000000000000000000000000000000000000000000000000000000001790529051606091600091829173ffffffffffffffffffffffffffffffffffffffff861691620029dd9190620038e6565b600060405180830381855afa9150503d806000811462002a1a576040519150601f19603f3d011682016040523d82523d6000602084013e62002a1f565b606091505b50915091508162002a66576040518060400160405280600781526020017f4e4f5f4e414d450000000000000000000000000000000000000000000000000081525062001d74565b62001d748162002f21565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f95d89b41000000000000000000000000000000000000000000000000000000001790529051606091600091829173ffffffffffffffffffffffffffffffffffffffff86169162002af59190620038e6565b600060405180830381855afa9150503d806000811462002b32576040519150601f19603f3d011682016040523d82523d6000602084013e62002b37565b606091505b50915091508162002a66576040518060400160405280600981526020017f4e4f5f53594d424f4c000000000000000000000000000000000000000000000081525062001d74565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f313ce5670000000000000000000000000000000000000000000000000000000017905290516000918291829173ffffffffffffffffffffffffffffffffffffffff86169162002c019190620038e6565b600060405180830381855afa9150503d806000811462002c3e576040519150601f19603f3d011682016040523d82523d6000602084013e62002c43565b606091505b509150915081801562002c57575080516020145b62002c6457601262001d74565b8080602001905181019062001d74919062004012565b60018055565b60685460ff1662002cbd576040517f5386698100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040517f1e5e34eea33501aecf2ebec9fe0e884a40804275ea7fe10b2ba084c8374308b390600090a1565b600881901c60008181526069602052604081208054600160ff861690811b91821892839055929091908183169003620009c9576040517f646cf55800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600062002dd9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16620031119092919063ffffffff16565b80519091501562001f22578080602001905181019062002dfa919062004032565b62001f22576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840162001324565b600054610100900460ff1662002c7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162001324565b6060604082511062002f435781806020019051810190620007a2919062004052565b8151602003620030d35760005b60208110801562002f9b575082818151811062002f715762002f7162003b8a565b01602001517fff000000000000000000000000000000000000000000000000000000000000001615155b1562002fb6578062002fad8162003be8565b91505062002f50565b8060000362002ffa57505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e4700000000000000000000000000006020820152919050565b60008167ffffffffffffffff81111562003018576200301862003891565b6040519080825280601f01601f19166020018201604052801562003043576020820181803683370190505b50905060005b82811015620030cb5784818151811062003067576200306762003b8a565b602001015160f81c60f81b82828151811062003087576200308762003b8a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535080620030c28162003be8565b91505062003049565b509392505050565b505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e470000000000000000000000000000602082015290565b919050565b606062001d748484600085856000808673ffffffffffffffffffffffffffffffffffffffff168587604051620031489190620038e6565b60006040518083038185875af1925050503d806000811462003187576040519150601f19603f3d011682016040523d82523d6000602084013e6200318c565b606091505b50915091506200319f87838387620031aa565b979650505050505050565b60608315620032455782516000036200323d5773ffffffffffffffffffffffffffffffffffffffff85163b6200323d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162001324565b508162001d74565b62001d7483838151156200325c5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620013249190620040d2565b611b6680620040e883390190565b803563ffffffff811681146200310c57600080fd5b73ffffffffffffffffffffffffffffffffffffffff81168114620032d857600080fd5b50565b60008060408385031215620032ef57600080fd5b620032fa83620032a0565b915060208301356200330c81620032b5565b809150509250929050565b8015158114620032d857600080fd5b60008083601f8401126200333957600080fd5b50813567ffffffffffffffff8111156200335257600080fd5b6020830191508360208285010111156200336b57600080fd5b9250929050565b6000806000806000608086880312156200338b57600080fd5b6200339686620032a0565b94506020860135620033a881620032b5565b93506040860135620033ba8162003317565b9250606086013567ffffffffffffffff811115620033d757600080fd5b620033e58882890162003326565b969995985093965092949392505050565b806104008101831015620007a257600080fd5b60008060008060008060008060008060006105208c8e0312156200342c57600080fd5b620034388d8d620033f6565b9a50620034496104008d01620032a0565b99506104208c013598506104408c013597506200346a6104608d01620032a0565b96506104808c01356200347d81620032b5565b95506200348e6104a08d01620032a0565b94506104c08c0135620034a181620032b5565b93506104e08c013592506105008c013567ffffffffffffffff811115620034c757600080fd5b620034d58e828f0162003326565b915080935050809150509295989b509295989b9093969950565b6000602082840312156200350257600080fd5b81356200350f81620032b5565b9392505050565b60ff81168114620032d857600080fd5b600080600080600080600060e0888a0312156200354257600080fd5b87356200354f8162003516565b96506200355f60208901620032a0565b955060408801356200357181620032b5565b94506200358160608901620032a0565b935060808801356200359381620032b5565b9699959850939692959460a0840135945060c09093013592915050565b600080600060608486031215620035c657600080fd5b620035d184620032a0565b92506020840135620035e381620032b5565b91506040840135620035f581620032b5565b809150509250925092565b6000602082840312156200361357600080fd5b5035919050565b600080600080600080600060a0888a0312156200363657600080fd5b6200364188620032a0565b965060208801356200365381620032b5565b9550604088013567ffffffffffffffff808211156200367157600080fd5b6200367f8b838c0162003326565b909750955060608a01359150808211156200369957600080fd5b50620036a88a828b0162003326565b9094509250506080880135620036be8162003516565b8091505092959891949750929550565b600080600080600080600060c0888a031215620036ea57600080fd5b620036f588620032a0565b965060208801356200370781620032b5565b95506040880135945060608801356200372081620032b5565b93506080880135620037328162003317565b925060a088013567ffffffffffffffff8111156200374f57600080fd5b6200375d8a828b0162003326565b989b979a50959850939692959293505050565b60008060008061046085870312156200378857600080fd5b843593506200379b8660208701620033f6565b9250620037ac6104208601620032a0565b939692955092936104400135925050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b600061010060ff8c16835263ffffffff808c16602085015273ffffffffffffffffffffffffffffffffffffffff808c166040860152818b166060860152808a166080860152508760a08501528160c0850152620038678285018789620037bd565b925080851660e085015250509a9950505050505050505050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60005b83811015620038dd578181015183820152602001620038c3565b50506000910152565b60008251620038fa818460208701620038c0565b9190910192915050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156200394e576200394e62003891565b604052919050565b600067ffffffffffffffff82111562003973576200397362003891565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112620039b157600080fd5b8135620039c8620039c28262003956565b62003904565b818152846020838601011115620039de57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060006060848603121562003a1157600080fd5b833567ffffffffffffffff8082111562003a2a57600080fd5b62003a38878388016200399f565b9450602086013591508082111562003a4f57600080fd5b5062003a5e868287016200399f565b9250506040840135620035f58162003516565b6000815180845262003a8b816020860160208601620038c0565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60608152600062003ad2606083018662003a71565b828103602084015262003ae6818662003a71565b91505060ff83166040830152949350505050565b63ffffffff86168152600073ffffffffffffffffffffffffffffffffffffffff8087166020840152808616604084015250608060608301526200319f608083018486620037bd565b73ffffffffffffffffffffffffffffffffffffffff8516815263ffffffff8416602082015260606040820152600062003b80606083018486620037bd565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820362003c1c5762003c1c62003bb9565b5060010190565b60608152600062003c39606083018789620037bd565b828103602084015262003c4e818688620037bd565b91505060ff831660408301529695505050505050565b6000835162003c78818460208801620038c0565b83519083019062003c8e818360208801620038c0565b01949350505050565b60006020828403121562003caa57600080fd5b5051919050565b81810381811115620007a257620007a262003bb9565b600061010060ff8b16835263ffffffff808b16602085015273ffffffffffffffffffffffffffffffffffffffff808b166040860152818a1660608601528089166080860152508660a08501528160c085015262003d278285018762003a71565b925080851660e085015250509998505050505050505050565b600181815b8085111562003d9f57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111562003d835762003d8362003bb9565b8085161562003d9157918102915b93841c939080029062003d45565b509250929050565b60008262003db857506001620007a2565b8162003dc757506000620007a2565b816001811462003de0576002811462003deb5762003e0b565b6001915050620007a2565b60ff84111562003dff5762003dff62003bb9565b50506001821b620007a2565b5060208310610133831016604e8410600b841016171562003e30575081810a620007a2565b62003e3c838362003d40565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111562003e715762003e7162003bb9565b029392505050565b60006200350f838362003da7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b6000808585111562003ec757600080fd5b8386111562003ed557600080fd5b5050820193919092039150565b7fffffffff00000000000000000000000000000000000000000000000000000000813581811691600485101562003f235780818660040360031b1b83161692505b505092915050565b600080600080600080600060e0888a03121562003f4757600080fd5b873562003f5481620032b5565b9650602088013562003f6681620032b5565b955060408801359450606088013593506080880135620035938162003516565b600080600080600080600080610100898b03121562003fa457600080fd5b883562003fb181620032b5565b9750602089013562003fc381620032b5565b96506040890135955060608901359450608089013562003fe38162003317565b935060a089013562003ff58162003516565b979a969950949793969295929450505060c08201359160e0013590565b6000602082840312156200402557600080fd5b81516200350f8162003516565b6000602082840312156200404557600080fd5b81516200350f8162003317565b6000602082840312156200406557600080fd5b815167ffffffffffffffff8111156200407d57600080fd5b8201601f810184136200408f57600080fd5b8051620040a0620039c28262003956565b818152856020838501011115620040b657600080fd5b620040c9826020830160208601620038c0565b95945050505050565b6020815260006200350f602083018462003a7156fe6101006040523480156200001257600080fd5b5060405162001b6638038062001b6683398101604081905262000035916200028d565b82826003620000458382620003a1565b506004620000548282620003a1565b50503360c0525060ff811660e052466080819052620000739062000080565b60a052506200046d915050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f620000ad6200012e565b805160209182012060408051808201825260018152603160f81b90840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b6060600380546200013f9062000312565b80601f01602080910402602001604051908101604052809291908181526020018280546200016d9062000312565b8015620001be5780601f106200019257610100808354040283529160200191620001be565b820191906000526020600020905b815481529060010190602001808311620001a057829003601f168201915b5050505050905090565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001f057600080fd5b81516001600160401b03808211156200020d576200020d620001c8565b604051601f8301601f19908116603f01168101908282118183101715620002385762000238620001c8565b816040528381526020925086838588010111156200025557600080fd5b600091505b838210156200027957858201830151818301840152908201906200025a565b600093810190920192909252949350505050565b600080600060608486031215620002a357600080fd5b83516001600160401b0380821115620002bb57600080fd5b620002c987838801620001de565b94506020860151915080821115620002e057600080fd5b50620002ef86828701620001de565b925050604084015160ff811681146200030757600080fd5b809150509250925092565b600181811c908216806200032757607f821691505b6020821081036200034857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200039c57600081815260208120601f850160051c81016020861015620003775750805b601f850160051c820191505b81811015620003985782815560010162000383565b5050505b505050565b81516001600160401b03811115620003bd57620003bd620001c8565b620003d581620003ce845462000312565b846200034e565b602080601f8311600181146200040d5760008415620003f45750858301515b600019600386901b1c1916600185901b17855562000398565b600085815260208120601f198616915b828110156200043e578886015182559484019460019091019084016200041d565b50858210156200045d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e0516116aa620004bc6000396000610237015260008181610307015281816105c001526106a70152600061053a015260008181610379015261050401526116aa6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063a457c2d71161008c578063d505accf11610066578063d505accf1461039b578063dd62ed3e146103ae578063ffa1ad74146103f457600080fd5b8063a457c2d71461034e578063a9059cbb14610361578063cd0d00961461037457600080fd5b806395d89b41116100bd57806395d89b41146102e75780639dc29fac146102ef578063a3c573eb1461030257600080fd5b806370a08231146102915780637ecebe00146102c757600080fd5b806330adf81f1161012f5780633644e515116101145780633644e51514610261578063395093511461026957806340c10f191461027c57600080fd5b806330adf81f14610209578063313ce5671461023057600080fd5b806318160ddd1161016057806318160ddd146101bd57806320606b70146101cf57806323b872dd146101f657600080fd5b806306fdde031461017c578063095ea7b31461019a575b600080fd5b610184610430565b60405161019191906113e4565b60405180910390f35b6101ad6101a8366004611479565b6104c2565b6040519015158152602001610191565b6002545b604051908152602001610191565b6101c17f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b6101ad6102043660046114a3565b6104dc565b6101c17f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610191565b6101c1610500565b6101ad610277366004611479565b61055c565b61028f61028a366004611479565b6105a8565b005b6101c161029f3660046114df565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101c16102d53660046114df565b60056020526000908152604090205481565b610184610680565b61028f6102fd366004611479565b61068f565b6103297f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610191565b6101ad61035c366004611479565b61075e565b6101ad61036f366004611479565b61082f565b6101c17f000000000000000000000000000000000000000000000000000000000000000081565b61028f6103a9366004611501565b61083d565b6101c16103bc366004611574565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101846040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525081565b60606003805461043f906115a7565b80601f016020809104026020016040519081016040528092919081815260200182805461046b906115a7565b80156104b85780601f1061048d576101008083540402835291602001916104b8565b820191906000526020600020905b81548152906001019060200180831161049b57829003601f168201915b5050505050905090565b6000336104d0818585610b73565b60019150505b92915050565b6000336104ea858285610d27565b6104f5858585610dfe565b506001949350505050565b60007f00000000000000000000000000000000000000000000000000000000000000004614610537576105324661106d565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906104d090829086906105a3908790611629565b610b73565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60448201527f6c79676f6e5a6b45564d4272696467650000000000000000000000000000000060648201526084015b60405180910390fd5b61067c8282611135565b5050565b60606004805461043f906115a7565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610754576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60448201527f6c79676f6e5a6b45564d427269646765000000000000000000000000000000006064820152608401610669565b61067c8282611228565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610822576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610669565b6104f58286868403610b73565b6000336104d0818585610dfe565b834211156108cc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f546f6b656e577261707065643a3a7065726d69743a204578706972656420706560448201527f726d6974000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260056020526040812080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918a918a918a9190866109268361163c565b9091555060408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610991610500565b6040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281019190915260428101839052606201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600080855291840180845281905260ff89169284019290925260608301879052608083018690529092509060019060a0016020604051602081039080840390855afa158015610a55573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811615801590610ad057508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b610b5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f546f6b656e577261707065643a3a7065726d69743a20496e76616c696420736960448201527f676e6174757265000000000000000000000000000000000000000000000000006064820152608401610669565b610b678a8a8a610b73565b50505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8216610cb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610df85781811015610deb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610669565b610df88484848403610b73565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610ea1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8216610f44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610ffa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610df8565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f611098610430565b8051602091820120604080518082018252600181527f310000000000000000000000000000000000000000000000000000000000000090840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b73ffffffffffffffffffffffffffffffffffffffff82166111b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610669565b80600260008282546111c49190611629565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff82166112cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015611381576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610d1a565b600060208083528351808285015260005b81811015611411578581018301518582016040015282016113f5565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461147457600080fd5b919050565b6000806040838503121561148c57600080fd5b61149583611450565b946020939093013593505050565b6000806000606084860312156114b857600080fd5b6114c184611450565b92506114cf60208501611450565b9150604084013590509250925092565b6000602082840312156114f157600080fd5b6114fa82611450565b9392505050565b600080600080600080600060e0888a03121561151c57600080fd5b61152588611450565b965061153360208901611450565b95506040880135945060608801359350608088013560ff8116811461155757600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561158757600080fd5b61159083611450565b915061159e60208401611450565b90509250929050565b600181811c908216806115bb57607f821691505b6020821081036115f4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156104d6576104d66115fa565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361166d5761166d6115fa565b506001019056fea26469706673582212208d88fee561cff7120d381c345cfc534cef8229a272dc5809d4bbb685ad67141164736f6c63430008110033a2646970667358221220addfd62f466d34ee002afbb4ae37b6be56ad421fe773f800badeb4ce1025089864736f6c63430008110033"
|
| 41 |
-
},
|
| 42 |
-
{
|
| 43 |
-
"contractName": "PolygonZkEVMBridge proxy",
|
| 44 |
-
"balance": "200000000000000000000000000",
|
| 45 |
-
"nonce": "1",
|
| 46 |
-
"address": "0xF6BEEeBB578e214CA9E23B0e9683454Ff88Ed2A7",
|
| 47 |
-
"bytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461088b565b610135565b61006b6100a33660046108a6565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461088b565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109bb602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b600061022161052a565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b61042283610552565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a16101748161059f565b60606000808573ffffffffffffffffffffffffffffffffffffffff16856040516104cf919061094d565b600060405180830381855af49150503d806000811461050a576040519150601f19603f3d011682016040523d82523d6000602084013e61050f565b606091505b5091509150610520868383876106ab565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b61055b81610753565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff8116610642576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561074157825160000361073a5773ffffffffffffffffffffffffffffffffffffffff85163b61073a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016103a2565b508161074b565b61074b838361081e565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff81163b6107f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610665565b81511561082e5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610969565b803573ffffffffffffffffffffffffffffffffffffffff8116811461088657600080fd5b919050565b60006020828403121561089d57600080fd5b6102b182610862565b6000806000604084860312156108bb57600080fd5b6108c484610862565b9250602084013567ffffffffffffffff808211156108e157600080fd5b818601915086601f8301126108f557600080fd5b81358181111561090457600080fd5b87602082850101111561091657600080fd5b6020830194508093505050509250925092565b60005b8381101561094457818101518382015260200161092c565b50506000910152565b6000825161095f818460208701610929565b9190910192915050565b6020815260008251806020840152610988816040850160208701610929565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220a1af0d6cb4f1e31496a4c5c1448913bce4bd6ad3a39e47c6f7190c114d6f9bf464736f6c63430008110033",
|
| 48 |
-
"storage": {
|
| 49 |
-
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 50 |
-
"0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 51 |
-
"0x0000000000000000000000000000000000000000000000000000000000000068": "0x00000000000000a40d5f56745a118d0906a34e69aec8c0db1cb8fa0000000100",
|
| 52 |
-
"0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0x00000000000000000000000040797c2f93298a44a893f43edf1b33b63d7ba333",
|
| 53 |
-
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0x00000000000000000000000039e780d8800f7396e8b7530a8925b14025aedc77"
|
| 54 |
-
}
|
| 55 |
-
},
|
| 56 |
-
{
|
| 57 |
-
"contractName": "PolygonZkEVMGlobalExitRootL2 implementation",
|
| 58 |
-
"balance": "0",
|
| 59 |
-
"nonce": "1",
|
| 60 |
-
"address": "0x77Fc57b154fCF8320Df2C2e6C044AA50141c023b",
|
| 61 |
-
"bytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806301fd904414610051578063257b36321461006d57806333d6247d1461008d578063a3c573eb146100a2575b600080fd5b61005a60015481565b6040519081526020015b60405180910390f35b61005a61007b366004610162565b60006020819052908152604090205481565b6100a061009b366004610162565b6100ee565b005b6100c97f000000000000000000000000f6beeebb578e214ca9e23b0e9683454ff88ed2a781565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610064565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000f6beeebb578e214ca9e23b0e9683454ff88ed2a7161461015d576040517fb49365dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600155565b60006020828403121561017457600080fd5b503591905056fea2646970667358221220a187fc278346c1b61c449ea3641002b6eac2bda3351a122a12c35099f933696864736f6c63430008110033"
|
| 62 |
-
},
|
| 63 |
-
{
|
| 64 |
-
"contractName": "PolygonZkEVMGlobalExitRootL2 proxy",
|
| 65 |
-
"balance": "0",
|
| 66 |
-
"nonce": "1",
|
| 67 |
-
"address": "0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa",
|
| 68 |
-
"bytecode": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106ca565b610118565b61005b6100933660046106e5565b61015f565b3480156100a457600080fd5b506100ad6101d0565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106ca565b61020b565b3480156100f557600080fd5b506100ad610235565b610106610292565b610116610111610331565b61033b565b565b61012061035f565b6001600160a01b0316336001600160a01b031614156101575761015481604051806020016040528060008152506000610392565b50565b6101546100fe565b61016761035f565b6001600160a01b0316336001600160a01b031614156101c8576101c38383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610392915050565b505050565b6101c36100fe565b60006101da61035f565b6001600160a01b0316336001600160a01b03161415610200576101fb610331565b905090565b6102086100fe565b90565b61021361035f565b6001600160a01b0316336001600160a01b0316141561015757610154816103f1565b600061023f61035f565b6001600160a01b0316336001600160a01b03161415610200576101fb61035f565b606061028583836040518060600160405280602781526020016107e460279139610445565b9392505050565b3b151590565b61029a61035f565b6001600160a01b0316336001600160a01b031614156101165760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b60006101fb610519565b3660008037600080366000845af43d6000803e80801561035a573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b61039b83610541565b6040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a26000825111806103dc5750805b156101c3576103eb8383610260565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61041a61035f565b604080516001600160a01b03928316815291841660208301520160405180910390a1610154816105e9565b6060833b6104a45760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610328565b600080856001600160a01b0316856040516104bf9190610794565b600060405180830381855af49150503d80600081146104fa576040519150601f19603f3d011682016040523d82523d6000602084013e6104ff565b606091505b509150915061050f828286610675565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610383565b803b6105a55760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610328565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5b80546001600160a01b0319166001600160a01b039290921691909117905550565b6001600160a01b03811661064e5760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610328565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61036105c8565b60608315610684575081610285565b8251156106945782518084602001fd5b8160405162461bcd60e51b815260040161032891906107b0565b80356001600160a01b03811681146106c557600080fd5b919050565b6000602082840312156106dc57600080fd5b610285826106ae565b6000806000604084860312156106fa57600080fd5b610703846106ae565b9250602084013567ffffffffffffffff8082111561072057600080fd5b818601915086601f83011261073457600080fd5b81358181111561074357600080fd5b87602082850101111561075557600080fd5b6020830194508093505050509250925092565b60005b8381101561078357818101518382015260200161076b565b838111156103eb5750506000910152565b600082516107a6818460208701610768565b9190910192915050565b60208152600082518060208401526107cf816040850160208701610768565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212204675187caf3a43285d9a2c1844a981e977bd52a85ff073e7fc649f73847d70a464736f6c63430008090033",
|
| 69 |
-
"storage": {
|
| 70 |
-
"0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0x00000000000000000000000040797c2f93298a44a893f43edf1b33b63d7ba333",
|
| 71 |
-
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0x00000000000000000000000077fc57b154fcf8320df2c2e6c044aa50141c023b"
|
| 72 |
-
}
|
| 73 |
-
},
|
| 74 |
-
{
|
| 75 |
-
"contractName": "PolygonZkEVMTimelock",
|
| 76 |
-
"balance": "0",
|
| 77 |
-
"nonce": "1",
|
| 78 |
-
"address": "0x02245d7B6CB0b6870d1e28AC877EE355b9588869",
|
| 79 |
-
"bytecode": "0x6080604052600436106101c65760003560e01c806364d62353116100f7578063b1c5f42711610095578063d547741f11610064578063d547741f14610661578063e38335e514610681578063f23a6e6114610694578063f27a0c92146106d957600080fd5b8063b1c5f427146105af578063bc197c81146105cf578063c4d252f514610614578063d45c44351461063457600080fd5b80638f61f4f5116100d15780638f61f4f5146104e157806391d1485414610515578063a217fddf14610566578063b08e51c01461057b57600080fd5b806364d62353146104815780638065657f146104a15780638f2a0bb0146104c157600080fd5b8063248a9ca31161016457806331d507501161013e57806331d50750146103c857806336568abe146103e85780633a6aae7214610408578063584b153e1461046157600080fd5b8063248a9ca3146103475780632ab0f529146103775780632f2ff15d146103a857600080fd5b80630d3cf6fc116101a05780630d3cf6fc1461026b578063134008d31461029f57806313bc9f20146102b2578063150b7a02146102d257600080fd5b806301d5062a146101d257806301ffc9a7146101f457806307bd02651461022957600080fd5b366101cd57005b600080fd5b3480156101de57600080fd5b506101f26101ed366004611c12565b6106ee565b005b34801561020057600080fd5b5061021461020f366004611c87565b610783565b60405190151581526020015b60405180910390f35b34801561023557600080fd5b5061025d7fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e6381565b604051908152602001610220565b34801561027757600080fd5b5061025d7f5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca581565b6101f26102ad366004611cc9565b6107df565b3480156102be57600080fd5b506102146102cd366004611d35565b6108d7565b3480156102de57600080fd5b506103166102ed366004611e5a565b7f150b7a0200000000000000000000000000000000000000000000000000000000949350505050565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610220565b34801561035357600080fd5b5061025d610362366004611d35565b60009081526020819052604090206001015490565b34801561038357600080fd5b50610214610392366004611d35565b6000908152600160208190526040909120541490565b3480156103b457600080fd5b506101f26103c3366004611ec2565b6108fd565b3480156103d457600080fd5b506102146103e3366004611d35565b610927565b3480156103f457600080fd5b506101f2610403366004611ec2565b610940565b34801561041457600080fd5b5061043c7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610220565b34801561046d57600080fd5b5061021461047c366004611d35565b6109f8565b34801561048d57600080fd5b506101f261049c366004611d35565b610a0e565b3480156104ad57600080fd5b5061025d6104bc366004611cc9565b610ade565b3480156104cd57600080fd5b506101f26104dc366004611f33565b610b1d565b3480156104ed57600080fd5b5061025d7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc181565b34801561052157600080fd5b50610214610530366004611ec2565b60009182526020828152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b34801561057257600080fd5b5061025d600081565b34801561058757600080fd5b5061025d7ffd643c72710c63c0180259aba6b2d05451e3591a24e58b62239378085726f78381565b3480156105bb57600080fd5b5061025d6105ca366004611fe5565b610d4f565b3480156105db57600080fd5b506103166105ea36600461210e565b7fbc197c810000000000000000000000000000000000000000000000000000000095945050505050565b34801561062057600080fd5b506101f261062f366004611d35565b610d94565b34801561064057600080fd5b5061025d61064f366004611d35565b60009081526001602052604090205490565b34801561066d57600080fd5b506101f261067c366004611ec2565b610e8f565b6101f261068f366004611fe5565b610eb4565b3480156106a057600080fd5b506103166106af3660046121b8565b7ff23a6e610000000000000000000000000000000000000000000000000000000095945050505050565b3480156106e557600080fd5b5061025d611161565b7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc161071881611204565b6000610728898989898989610ade565b90506107348184611211565b6000817f4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca8b8b8b8b8b8a60405161077096959493929190612266565b60405180910390a3505050505050505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e00000000000000000000000000000000000000000000000000000000014806107d957506107d98261135e565b92915050565b600080527fdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d70696020527f5ba6852781629bcdcd4bdaa6de76d786f1c64b16acdac474e55bebc0ea157951547fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e639060ff1661085c5761085c81336113f5565b600061086c888888888888610ade565b905061087881856114ad565b610884888888886115ea565b6000817fc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b588a8a8a8a6040516108bc94939291906122b1565b60405180910390a36108cd816116ee565b5050505050505050565b6000818152600160205260408120546001811180156108f65750428111155b9392505050565b60008281526020819052604090206001015461091881611204565b6109228383611797565b505050565b60008181526001602052604081205481905b1192915050565b73ffffffffffffffffffffffffffffffffffffffff811633146109ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084015b60405180910390fd5b6109f48282611887565b5050565b6000818152600160208190526040822054610939565b333014610a9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f54696d656c6f636b436f6e74726f6c6c65723a2063616c6c6572206d7573742060448201527f62652074696d656c6f636b00000000000000000000000000000000000000000060648201526084016109e1565b60025460408051918252602082018390527f11c24f4ead16507c69ac467fbd5e4eed5fb5c699626d2cc6d66421df253886d5910160405180910390a1600255565b6000868686868686604051602001610afb96959493929190612266565b6040516020818303038152906040528051906020012090509695505050505050565b7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc1610b4781611204565b888714610bd6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b888514610c65576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b6000610c778b8b8b8b8b8b8b8b610d4f565b9050610c838184611211565b60005b8a811015610d415780827f4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca8e8e85818110610cc357610cc36122f1565b9050602002016020810190610cd89190612320565b8d8d86818110610cea57610cea6122f1565b905060200201358c8c87818110610d0357610d036122f1565b9050602002810190610d15919061233b565b8c8b604051610d2996959493929190612266565b60405180910390a3610d3a816123cf565b9050610c86565b505050505050505050505050565b60008888888888888888604051602001610d709897969594939291906124b7565b60405160208183030381529060405280519060200120905098975050505050505050565b7ffd643c72710c63c0180259aba6b2d05451e3591a24e58b62239378085726f783610dbe81611204565b610dc7826109f8565b610e53576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20636160448201527f6e6e6f742062652063616e63656c6c656400000000000000000000000000000060648201526084016109e1565b6000828152600160205260408082208290555183917fbaa1eb22f2a492ba1a5fea61b8df4d27c6c8b5f3971e63bb58fa14ff72eedb7091a25050565b600082815260208190526040902060010154610eaa81611204565b6109228383611887565b600080527fdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d70696020527f5ba6852781629bcdcd4bdaa6de76d786f1c64b16acdac474e55bebc0ea157951547fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e639060ff16610f3157610f3181336113f5565b878614610fc0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b87841461104f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b60006110618a8a8a8a8a8a8a8a610d4f565b905061106d81856114ad565b60005b8981101561114b5760008b8b8381811061108c5761108c6122f1565b90506020020160208101906110a19190612320565b905060008a8a848181106110b7576110b76122f1565b9050602002013590503660008a8a868181106110d5576110d56122f1565b90506020028101906110e7919061233b565b915091506110f7848484846115ea565b84867fc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b588686868660405161112e94939291906122b1565b60405180910390a35050505080611144906123cf565b9050611070565b50611155816116ee565b50505050505050505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166315064c966040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111f2919061257e565b156111fd5750600090565b5060025490565b61120e81336113f5565b50565b61121a82610927565b156112a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20616c60448201527f7265616479207363686564756c6564000000000000000000000000000000000060648201526084016109e1565b6112af611161565b81101561133e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f54696d656c6f636b436f6e74726f6c6c65723a20696e73756666696369656e7460448201527f2064656c6179000000000000000000000000000000000000000000000000000060648201526084016109e1565b61134881426125a0565b6000928352600160205260409092209190915550565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b0000000000000000000000000000000000000000000000000000000014806107d957507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146107d9565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166109f4576114338161193e565b61143e83602061195d565b60405160200161144f9291906125d7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a00000000000000000000000000000000000000000000000000000000082526109e191600401612658565b6114b6826108d7565b611542576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20697360448201527f206e6f742072656164790000000000000000000000000000000000000000000060648201526084016109e1565b80158061155e5750600081815260016020819052604090912054145b6109f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f54696d656c6f636b436f6e74726f6c6c65723a206d697373696e67206465706560448201527f6e64656e6379000000000000000000000000000000000000000000000000000060648201526084016109e1565b60008473ffffffffffffffffffffffffffffffffffffffff168484846040516116149291906126a9565b60006040518083038185875af1925050503d8060008114611651576040519150601f19603f3d011682016040523d82523d6000602084013e611656565b606091505b50509050806116e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603360248201527f54696d656c6f636b436f6e74726f6c6c65723a20756e6465726c79696e67207460448201527f72616e73616374696f6e2072657665727465640000000000000000000000000060648201526084016109e1565b5050505050565b6116f7816108d7565b611783576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20697360448201527f206e6f742072656164790000000000000000000000000000000000000000000060648201526084016109e1565b600090815260016020819052604090912055565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166109f45760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556118293390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16156109f45760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60606107d973ffffffffffffffffffffffffffffffffffffffff831660145b6060600061196c8360026126b9565b6119779060026125a0565b67ffffffffffffffff81111561198f5761198f611d4e565b6040519080825280601f01601f1916602001820160405280156119b9576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106119f0576119f06122f1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611a5357611a536122f1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000611a8f8460026126b9565b611a9a9060016125a0565b90505b6001811115611b37577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110611adb57611adb6122f1565b1a60f81b828281518110611af157611af16122f1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c93611b30816126d0565b9050611a9d565b5083156108f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016109e1565b803573ffffffffffffffffffffffffffffffffffffffff81168114611bc457600080fd5b919050565b60008083601f840112611bdb57600080fd5b50813567ffffffffffffffff811115611bf357600080fd5b602083019150836020828501011115611c0b57600080fd5b9250929050565b600080600080600080600060c0888a031215611c2d57600080fd5b611c3688611ba0565b965060208801359550604088013567ffffffffffffffff811115611c5957600080fd5b611c658a828b01611bc9565b989b979a50986060810135976080820135975060a09091013595509350505050565b600060208284031215611c9957600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146108f657600080fd5b60008060008060008060a08789031215611ce257600080fd5b611ceb87611ba0565b955060208701359450604087013567ffffffffffffffff811115611d0e57600080fd5b611d1a89828a01611bc9565b979a9699509760608101359660809091013595509350505050565b600060208284031215611d4757600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611dc457611dc4611d4e565b604052919050565b600082601f830112611ddd57600080fd5b813567ffffffffffffffff811115611df757611df7611d4e565b611e2860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611d7d565b818152846020838601011115611e3d57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215611e7057600080fd5b611e7985611ba0565b9350611e8760208601611ba0565b925060408501359150606085013567ffffffffffffffff811115611eaa57600080fd5b611eb687828801611dcc565b91505092959194509250565b60008060408385031215611ed557600080fd5b82359150611ee560208401611ba0565b90509250929050565b60008083601f840112611f0057600080fd5b50813567ffffffffffffffff811115611f1857600080fd5b6020830191508360208260051b8501011115611c0b57600080fd5b600080600080600080600080600060c08a8c031215611f5157600080fd5b893567ffffffffffffffff80821115611f6957600080fd5b611f758d838e01611eee565b909b50995060208c0135915080821115611f8e57600080fd5b611f9a8d838e01611eee565b909950975060408c0135915080821115611fb357600080fd5b50611fc08c828d01611eee565b9a9d999c50979a969997986060880135976080810135975060a0013595509350505050565b60008060008060008060008060a0898b03121561200157600080fd5b883567ffffffffffffffff8082111561201957600080fd5b6120258c838d01611eee565b909a50985060208b013591508082111561203e57600080fd5b61204a8c838d01611eee565b909850965060408b013591508082111561206357600080fd5b506120708b828c01611eee565b999c989b509699959896976060870135966080013595509350505050565b600082601f83011261209f57600080fd5b8135602067ffffffffffffffff8211156120bb576120bb611d4e565b8160051b6120ca828201611d7d565b92835284810182019282810190878511156120e457600080fd5b83870192505b84831015612103578235825291830191908301906120ea565b979650505050505050565b600080600080600060a0868803121561212657600080fd5b61212f86611ba0565b945061213d60208701611ba0565b9350604086013567ffffffffffffffff8082111561215a57600080fd5b61216689838a0161208e565b9450606088013591508082111561217c57600080fd5b61218889838a0161208e565b9350608088013591508082111561219e57600080fd5b506121ab88828901611dcc565b9150509295509295909350565b600080600080600060a086880312156121d057600080fd5b6121d986611ba0565b94506121e760208701611ba0565b93506040860135925060608601359150608086013567ffffffffffffffff81111561221157600080fd5b6121ab88828901611dcc565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff8716815285602082015260a06040820152600061229c60a08301868861221d565b60608301949094525060800152949350505050565b73ffffffffffffffffffffffffffffffffffffffff851681528360208201526060604082015260006122e760608301848661221d565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561233257600080fd5b6108f682611ba0565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261237057600080fd5b83018035915067ffffffffffffffff82111561238b57600080fd5b602001915036819003821315611c0b57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612400576124006123a0565b5060010190565b81835260006020808501808196508560051b810191508460005b878110156124aa57828403895281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe188360301811261246057600080fd5b8701858101903567ffffffffffffffff81111561247c57600080fd5b80360382131561248b57600080fd5b61249686828461221d565b9a87019a9550505090840190600101612421565b5091979650505050505050565b60a0808252810188905260008960c08301825b8b8110156125055773ffffffffffffffffffffffffffffffffffffffff6124f084611ba0565b168252602092830192909101906001016124ca565b5083810360208501528881527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff89111561253e57600080fd5b8860051b9150818a602083013701828103602090810160408501526125669082018789612407565b60608401959095525050608001529695505050505050565b60006020828403121561259057600080fd5b815180151581146108f657600080fd5b808201808211156107d9576107d96123a0565b60005b838110156125ce5781810151838201526020016125b6565b50506000910152565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161260f8160178501602088016125b3565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000601791840191820152835161264c8160288401602088016125b3565b01602801949350505050565b60208152600082518060208401526126778160408501602087016125b3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b8183823760009101908152919050565b80820281158282048414176107d9576107d96123a0565b6000816126df576126df6123a0565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea2646970667358221220288c3dd40a2ba96edf066502722584177809ebdb47c0cf9ee8df6f07954c373064736f6c63430008110033",
|
| 80 |
-
"storage": {
|
| 81 |
-
"0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000015180",
|
| 82 |
-
"0xbdd73c6ebfb442c137537be0985acf11af8e6133078bc51ef9094071cb0ca475": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 83 |
-
"0x92b79801e6a3d148a516c908cc0bbad93771fa74468b7757a14aa55532d092de": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 84 |
-
"0x64494413541ff93b31aa309254e3fed72a7456e9845988b915b4c7a7ceba8814": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5",
|
| 85 |
-
"0x43e090632490f7d46c400129311fff008a7688bb3d4aebdf80607456b452cf04": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 86 |
-
"0x3412d5605ac6cd444957cedb533e5dacad6378b4bc819ebe3652188a665066d6": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5",
|
| 87 |
-
"0x5af21cf0316499c6925cf9be0331b8bd150a1fa4c19d24a043b45f0cf15357c3": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 88 |
-
"0xdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d706a": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5",
|
| 89 |
-
"0xaf021eeb38644155cd697b3ce0ec4fdac818d29c448a9f9d9bafc293723c6cd8": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
| 90 |
-
"0xc3ad33e20b0c56a223ad5104fff154aa010f8715b9c981fd38fdc60a4d1a52fc": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5"
|
| 91 |
-
}
|
| 92 |
-
},
|
| 93 |
-
{
|
| 94 |
-
"accountName": "keyless Deployer",
|
| 95 |
-
"balance": "0",
|
| 96 |
-
"nonce": "1",
|
| 97 |
-
"address": "0xB83a574B3966F7dc1d38d162FA154F2A57D608Bb"
|
| 98 |
-
},
|
| 99 |
-
{
|
| 100 |
-
"accountName": "deployer",
|
| 101 |
-
"balance": "0",
|
| 102 |
-
"nonce": "8",
|
| 103 |
-
"address": "0xA0B02B28920812324f1cC3255bd8840867d3f227"
|
| 104 |
-
}
|
| 105 |
-
]
|
| 106 |
-
}
|
| 107 |
-
|
| 108 |
-
`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -38,3 +38,13 @@
|
|
| 38 |
},
|
| 39 |
}
|
| 40 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
},
|
| 39 |
}
|
| 40 |
}
|
| 41 |
+
|
| 42 |
+
// MarshalJSON marshalls time duration into text.
|
| 43 |
+
func (d Duration) MarshalJSON() ([]byte, error) {
|
| 44 |
+
return []byte(`"` + d.String() + `"`), nil
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
// MarshalText marshalls time duration into text.
|
| 48 |
+
func (d *Duration) MarshalText() ([]byte, error) {
|
| 49 |
+
return []byte(d.String()), nil
|
| 50 |
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package dataavailability
|
| 2 |
+
|
| 3 |
+
// DABackendType is the data availability protocol for the CDK
|
| 4 |
+
type DABackendType string
|
| 5 |
+
|
| 6 |
+
const (
|
| 7 |
+
// DataAvailabilityCommittee is the DAC protocol backend
|
| 8 |
+
DataAvailabilityCommittee DABackendType = "DataAvailabilityCommittee"
|
| 9 |
+
)
|
|
@@ -0,0 +1,152 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package dataavailability
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"context"
|
| 5 |
+
"fmt"
|
| 6 |
+
"math/big"
|
| 7 |
+
|
| 8 |
+
"github.com/0xPolygonHermez/zkevm-node/etherman/types"
|
| 9 |
+
jsontypes "github.com/0xPolygonHermez/zkevm-node/jsonrpc/types"
|
| 10 |
+
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 11 |
+
"github.com/ethereum/go-ethereum/common"
|
| 12 |
+
"github.com/ethereum/go-ethereum/crypto"
|
| 13 |
+
)
|
| 14 |
+
|
| 15 |
+
const (
|
| 16 |
+
unexpectedHashTemplate = "mismatch on transaction data for batch num %d. Expected hash %s, actual hash: %s"
|
| 17 |
+
failedDataRetrievalTemplate = "failed to retrieve local data for batches %v: %s"
|
| 18 |
+
invalidBatchRetrievalArgs = "invalid L2 batch data retrieval arguments, %d != %d"
|
| 19 |
+
)
|
| 20 |
+
|
| 21 |
+
// DataAvailability implements an abstract data availability integration
|
| 22 |
+
type DataAvailability struct {
|
| 23 |
+
isTrustedSequencer bool
|
| 24 |
+
|
| 25 |
+
state stateInterface
|
| 26 |
+
zkEVMClient ZKEVMClientTrustedBatchesGetter
|
| 27 |
+
backend DABackender
|
| 28 |
+
|
| 29 |
+
ctx context.Context
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
// New creates a DataAvailability instance
|
| 33 |
+
func New(
|
| 34 |
+
isTrustedSequencer bool,
|
| 35 |
+
backend DABackender,
|
| 36 |
+
state stateInterface,
|
| 37 |
+
zkEVMClient ZKEVMClientTrustedBatchesGetter,
|
| 38 |
+
) (*DataAvailability, error) {
|
| 39 |
+
da := &DataAvailability{
|
| 40 |
+
isTrustedSequencer: isTrustedSequencer,
|
| 41 |
+
backend: backend,
|
| 42 |
+
state: state,
|
| 43 |
+
zkEVMClient: zkEVMClient,
|
| 44 |
+
ctx: context.Background(),
|
| 45 |
+
}
|
| 46 |
+
err := da.backend.Init()
|
| 47 |
+
return da, err
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
// PostSequence sends the sequence data to the data availability backend, and returns the dataAvailabilityMessage
|
| 51 |
+
// as expected by the contract
|
| 52 |
+
func (d *DataAvailability) PostSequence(ctx context.Context, sequences []types.Sequence) ([]byte, error) {
|
| 53 |
+
batchesData := [][]byte{}
|
| 54 |
+
for _, batch := range sequences {
|
| 55 |
+
// Do not send to the DA backend data that will be stored to L1
|
| 56 |
+
if batch.ForcedBatchTimestamp == 0 {
|
| 57 |
+
batchesData = append(batchesData, batch.BatchL2Data)
|
| 58 |
+
}
|
| 59 |
+
}
|
| 60 |
+
return d.backend.PostSequence(ctx, batchesData)
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
// GetBatchL2Data tries to return the data from a batch, in the following priorities. batchNums should not include forced batches.
|
| 64 |
+
// 1. From local DB
|
| 65 |
+
// 2. From Trusted Sequencer (if not self)
|
| 66 |
+
// 3. From DA backend
|
| 67 |
+
func (d *DataAvailability) GetBatchL2Data(batchNums []uint64, batchHashes []common.Hash, dataAvailabilityMessage []byte) ([][]byte, error) {
|
| 68 |
+
if len(batchNums) != len(batchHashes) {
|
| 69 |
+
return nil, fmt.Errorf(invalidBatchRetrievalArgs, len(batchNums), len(batchHashes))
|
| 70 |
+
}
|
| 71 |
+
localData, err := d.state.GetBatchL2DataByNumbers(d.ctx, batchNums, nil)
|
| 72 |
+
if err != nil {
|
| 73 |
+
return nil, err
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
data, err := checkBatches(batchNums, batchHashes, localData)
|
| 77 |
+
if err != nil {
|
| 78 |
+
log.Warnf(failedDataRetrievalTemplate, batchNums, err.Error())
|
| 79 |
+
} else {
|
| 80 |
+
return data, nil
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
if !d.isTrustedSequencer {
|
| 84 |
+
data, err = d.rpcData(batchNums, batchHashes, d.zkEVMClient.BatchesByNumbers)
|
| 85 |
+
if err != nil {
|
| 86 |
+
log.Warnf(failedDataRetrievalTemplate, batchNums, err.Error())
|
| 87 |
+
} else {
|
| 88 |
+
return data, nil
|
| 89 |
+
}
|
| 90 |
+
}
|
| 91 |
+
return d.backend.GetSequence(d.ctx, batchHashes, dataAvailabilityMessage)
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
func checkBatches(batchNumbers []uint64, expectedHashes []common.Hash, batchData map[uint64][]byte) ([][]byte, error) {
|
| 95 |
+
if len(batchNumbers) != len(expectedHashes) {
|
| 96 |
+
return nil, fmt.Errorf("invalid batch parameters")
|
| 97 |
+
}
|
| 98 |
+
result := make([][]byte, len(batchNumbers))
|
| 99 |
+
for i := 0; i < len(batchNumbers); i++ {
|
| 100 |
+
batchNumber := batchNumbers[i]
|
| 101 |
+
expectedHash := expectedHashes[i]
|
| 102 |
+
bd, ok := batchData[batchNumber]
|
| 103 |
+
if !ok {
|
| 104 |
+
return nil, fmt.Errorf("missing batch data: [%d] %s", batchNumber, expectedHash.Hex())
|
| 105 |
+
}
|
| 106 |
+
actualHash := crypto.Keccak256Hash(bd)
|
| 107 |
+
if actualHash != expectedHash {
|
| 108 |
+
err := fmt.Errorf(unexpectedHashTemplate, batchNumber, expectedHash, actualHash)
|
| 109 |
+
log.Warnf("wrong local data for hash: %s", err.Error())
|
| 110 |
+
return nil, err
|
| 111 |
+
}
|
| 112 |
+
result[i] = bd
|
| 113 |
+
}
|
| 114 |
+
return result, nil
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
type rpcBatchDataFunc func(ctx context.Context, numbers []*big.Int) ([]*jsontypes.BatchData, error)
|
| 118 |
+
|
| 119 |
+
// rpcData retrieves batch data from rpcBatchDataFunc, returns an error unless all are found and correct
|
| 120 |
+
func (d *DataAvailability) rpcData(batchNums []uint64, expectedHashes []common.Hash, rpcFunc rpcBatchDataFunc) ([][]byte, error) {
|
| 121 |
+
if len(batchNums) != len(expectedHashes) {
|
| 122 |
+
return nil, fmt.Errorf("invalid arguments, len of batch numbers does not equal length of expected hashes: %d != %d",
|
| 123 |
+
len(batchNums), len(expectedHashes))
|
| 124 |
+
}
|
| 125 |
+
nums := make([]*big.Int, 0, len(batchNums))
|
| 126 |
+
for _, n := range batchNums {
|
| 127 |
+
nums = append(nums, new(big.Int).SetUint64(n))
|
| 128 |
+
}
|
| 129 |
+
batchData, err := rpcFunc(d.ctx, nums)
|
| 130 |
+
if err != nil {
|
| 131 |
+
return nil, err
|
| 132 |
+
}
|
| 133 |
+
if len(batchData) != len(batchNums) {
|
| 134 |
+
return nil, fmt.Errorf("missing batch data, expected %d, got %d", len(batchNums), len(batchData))
|
| 135 |
+
}
|
| 136 |
+
result := make(map[uint64][]byte)
|
| 137 |
+
for i := 0; i < len(batchNums); i++ {
|
| 138 |
+
number := batchNums[i]
|
| 139 |
+
batch := batchData[i]
|
| 140 |
+
expectedTransactionsHash := expectedHashes[i]
|
| 141 |
+
actualTransactionsHash := crypto.Keccak256Hash(batch.BatchL2Data)
|
| 142 |
+
if expectedTransactionsHash != actualTransactionsHash {
|
| 143 |
+
return nil, fmt.Errorf(unexpectedHashTemplate, number, expectedTransactionsHash, actualTransactionsHash)
|
| 144 |
+
}
|
| 145 |
+
result[number] = batch.BatchL2Data
|
| 146 |
+
}
|
| 147 |
+
checked, err := checkBatches(batchNums, expectedHashes, result)
|
| 148 |
+
if err != nil {
|
| 149 |
+
return nil, err
|
| 150 |
+
}
|
| 151 |
+
return checked, nil
|
| 152 |
+
}
|
|
@@ -0,0 +1,309 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package datacommittee
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"crypto/ecdsa"
|
| 5 |
+
"errors"
|
| 6 |
+
"fmt"
|
| 7 |
+
"math/big"
|
| 8 |
+
"math/rand"
|
| 9 |
+
"sort"
|
| 10 |
+
"strings"
|
| 11 |
+
|
| 12 |
+
"github.com/0xPolygon/cdk-data-availability/client"
|
| 13 |
+
daTypes "github.com/0xPolygon/cdk-data-availability/types"
|
| 14 |
+
"github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/polygondatacommittee"
|
| 15 |
+
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 16 |
+
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
| 17 |
+
"github.com/ethereum/go-ethereum/common"
|
| 18 |
+
"github.com/ethereum/go-ethereum/crypto"
|
| 19 |
+
"github.com/ethereum/go-ethereum/ethclient"
|
| 20 |
+
"golang.org/x/net/context"
|
| 21 |
+
)
|
| 22 |
+
|
| 23 |
+
const unexpectedHashTemplate = "missmatch on transaction data. Expected hash %s, actual hash: %s"
|
| 24 |
+
|
| 25 |
+
// DataCommitteeMember represents a member of the Data Committee
|
| 26 |
+
type DataCommitteeMember struct {
|
| 27 |
+
Addr common.Address
|
| 28 |
+
URL string
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
// DataCommittee represents a specific committee
|
| 32 |
+
type DataCommittee struct {
|
| 33 |
+
AddressesHash common.Hash
|
| 34 |
+
Members []DataCommitteeMember
|
| 35 |
+
RequiredSignatures uint64
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
// DataCommitteeBackend implements the DAC integration
|
| 39 |
+
type DataCommitteeBackend struct {
|
| 40 |
+
dataCommitteeContract *polygondatacommittee.Polygondatacommittee
|
| 41 |
+
privKey *ecdsa.PrivateKey
|
| 42 |
+
dataCommitteeClientFactory client.Factory
|
| 43 |
+
|
| 44 |
+
committeeMembers []DataCommitteeMember
|
| 45 |
+
selectedCommitteeMember int
|
| 46 |
+
ctx context.Context
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
// New creates an instance of DataCommitteeBackend
|
| 50 |
+
func New(
|
| 51 |
+
l1RPCURL string,
|
| 52 |
+
dataCommitteeAddr common.Address,
|
| 53 |
+
privKey *ecdsa.PrivateKey,
|
| 54 |
+
dataCommitteeClientFactory client.Factory,
|
| 55 |
+
) (*DataCommitteeBackend, error) {
|
| 56 |
+
ethClient, err := ethclient.Dial(l1RPCURL)
|
| 57 |
+
if err != nil {
|
| 58 |
+
log.Errorf("error connecting to %s: %+v", l1RPCURL, err)
|
| 59 |
+
return nil, err
|
| 60 |
+
}
|
| 61 |
+
dataCommittee, err := polygondatacommittee.NewPolygondatacommittee(dataCommitteeAddr, ethClient)
|
| 62 |
+
if err != nil {
|
| 63 |
+
return nil, err
|
| 64 |
+
}
|
| 65 |
+
return &DataCommitteeBackend{
|
| 66 |
+
dataCommitteeContract: dataCommittee,
|
| 67 |
+
privKey: privKey,
|
| 68 |
+
dataCommitteeClientFactory: dataCommitteeClientFactory,
|
| 69 |
+
ctx: context.Background(),
|
| 70 |
+
}, nil
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
// Init loads the DAC to be cached when needed
|
| 74 |
+
func (d *DataCommitteeBackend) Init() error {
|
| 75 |
+
committee, err := d.getCurrentDataCommittee()
|
| 76 |
+
if err != nil {
|
| 77 |
+
return err
|
| 78 |
+
}
|
| 79 |
+
selectedCommitteeMember := -1
|
| 80 |
+
if committee != nil {
|
| 81 |
+
d.committeeMembers = committee.Members
|
| 82 |
+
if len(committee.Members) > 0 {
|
| 83 |
+
selectedCommitteeMember = rand.Intn(len(committee.Members)) //nolint:gosec
|
| 84 |
+
}
|
| 85 |
+
}
|
| 86 |
+
d.selectedCommitteeMember = selectedCommitteeMember
|
| 87 |
+
return nil
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
// GetSequence gets backend data one hash at a time. This should be optimized on the DAC side to get them all at once.
|
| 91 |
+
func (d *DataCommitteeBackend) GetSequence(ctx context.Context, hashes []common.Hash, dataAvailabilityMessage []byte) ([][]byte, error) {
|
| 92 |
+
// TODO: optimize this on the DAC side by implementing a multi batch retrieve api
|
| 93 |
+
var batchData [][]byte
|
| 94 |
+
for _, h := range hashes {
|
| 95 |
+
data, err := d.GetBatchL2Data(h)
|
| 96 |
+
if err != nil {
|
| 97 |
+
return nil, err
|
| 98 |
+
}
|
| 99 |
+
batchData = append(batchData, data)
|
| 100 |
+
}
|
| 101 |
+
return batchData, nil
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
// GetBatchL2Data returns the data from the DAC. It checks that it matches with the expected hash
|
| 105 |
+
func (d *DataCommitteeBackend) GetBatchL2Data(hash common.Hash) ([]byte, error) {
|
| 106 |
+
intialMember := d.selectedCommitteeMember
|
| 107 |
+
found := false
|
| 108 |
+
for !found && intialMember != -1 {
|
| 109 |
+
member := d.committeeMembers[d.selectedCommitteeMember]
|
| 110 |
+
log.Infof("trying to get data from %s at %s", member.Addr.Hex(), member.URL)
|
| 111 |
+
c := d.dataCommitteeClientFactory.New(member.URL)
|
| 112 |
+
data, err := c.GetOffChainData(d.ctx, hash)
|
| 113 |
+
if err != nil {
|
| 114 |
+
log.Warnf(
|
| 115 |
+
"error getting data from DAC node %s at %s: %s",
|
| 116 |
+
member.Addr.Hex(), member.URL, err,
|
| 117 |
+
)
|
| 118 |
+
d.selectedCommitteeMember = (d.selectedCommitteeMember + 1) % len(d.committeeMembers)
|
| 119 |
+
if d.selectedCommitteeMember == intialMember {
|
| 120 |
+
break
|
| 121 |
+
}
|
| 122 |
+
continue
|
| 123 |
+
}
|
| 124 |
+
actualTransactionsHash := crypto.Keccak256Hash(data)
|
| 125 |
+
if actualTransactionsHash != hash {
|
| 126 |
+
unexpectedHash := fmt.Errorf(
|
| 127 |
+
unexpectedHashTemplate, hash, actualTransactionsHash,
|
| 128 |
+
)
|
| 129 |
+
log.Warnf(
|
| 130 |
+
"error getting data from DAC node %s at %s: %s",
|
| 131 |
+
member.Addr.Hex(), member.URL, unexpectedHash,
|
| 132 |
+
)
|
| 133 |
+
d.selectedCommitteeMember = (d.selectedCommitteeMember + 1) % len(d.committeeMembers)
|
| 134 |
+
if d.selectedCommitteeMember == intialMember {
|
| 135 |
+
break
|
| 136 |
+
}
|
| 137 |
+
continue
|
| 138 |
+
}
|
| 139 |
+
return data, nil
|
| 140 |
+
}
|
| 141 |
+
if err := d.Init(); err != nil {
|
| 142 |
+
return nil, fmt.Errorf("error loading data committee: %s", err)
|
| 143 |
+
}
|
| 144 |
+
return nil, fmt.Errorf("couldn't get the data from any committee member")
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
type signatureMsg struct {
|
| 148 |
+
addr common.Address
|
| 149 |
+
signature []byte
|
| 150 |
+
err error
|
| 151 |
+
}
|
| 152 |
+
|
| 153 |
+
// PostSequence sends the sequence data to the data availability backend, and returns the dataAvailabilityMessage
|
| 154 |
+
// as expected by the contract
|
| 155 |
+
func (s *DataCommitteeBackend) PostSequence(ctx context.Context, batchesData [][]byte) ([]byte, error) {
|
| 156 |
+
// Get current committee
|
| 157 |
+
committee, err := s.getCurrentDataCommittee()
|
| 158 |
+
if err != nil {
|
| 159 |
+
return nil, err
|
| 160 |
+
}
|
| 161 |
+
|
| 162 |
+
// Authenticate as trusted sequencer by signing the sequences
|
| 163 |
+
sequence := daTypes.Sequence{}
|
| 164 |
+
for _, seq := range batchesData {
|
| 165 |
+
sequence = append(sequence, seq)
|
| 166 |
+
}
|
| 167 |
+
signedSequence, err := sequence.Sign(s.privKey)
|
| 168 |
+
if err != nil {
|
| 169 |
+
return nil, err
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
// Request signatures to all members in parallel
|
| 173 |
+
ch := make(chan signatureMsg, len(committee.Members))
|
| 174 |
+
signatureCtx, cancelSignatureCollection := context.WithCancel(ctx)
|
| 175 |
+
for _, member := range committee.Members {
|
| 176 |
+
go requestSignatureFromMember(signatureCtx, *signedSequence, member, ch)
|
| 177 |
+
}
|
| 178 |
+
|
| 179 |
+
// Collect signatures
|
| 180 |
+
msgs := []signatureMsg{}
|
| 181 |
+
var (
|
| 182 |
+
collectedSignatures uint64
|
| 183 |
+
failedToCollect uint64
|
| 184 |
+
)
|
| 185 |
+
for collectedSignatures < committee.RequiredSignatures {
|
| 186 |
+
msg := <-ch
|
| 187 |
+
if msg.err != nil {
|
| 188 |
+
log.Errorf("error when trying to get signature from %s: %s", msg.addr, msg.err)
|
| 189 |
+
failedToCollect++
|
| 190 |
+
if len(committee.Members)-int(failedToCollect) < int(committee.RequiredSignatures) {
|
| 191 |
+
cancelSignatureCollection()
|
| 192 |
+
return nil, errors.New("too many members failed to send their signature")
|
| 193 |
+
}
|
| 194 |
+
} else {
|
| 195 |
+
log.Infof("received signature from %s", msg.addr)
|
| 196 |
+
collectedSignatures++
|
| 197 |
+
}
|
| 198 |
+
msgs = append(msgs, msg)
|
| 199 |
+
}
|
| 200 |
+
|
| 201 |
+
// Stop requesting as soon as we have N valid signatures
|
| 202 |
+
cancelSignatureCollection()
|
| 203 |
+
|
| 204 |
+
return buildSignaturesAndAddrs(signatureMsgs(msgs), committee.Members), nil
|
| 205 |
+
}
|
| 206 |
+
|
| 207 |
+
func requestSignatureFromMember(ctx context.Context, signedSequence daTypes.SignedSequence, member DataCommitteeMember, ch chan signatureMsg) {
|
| 208 |
+
// request
|
| 209 |
+
c := client.New(member.URL)
|
| 210 |
+
log.Infof("sending request to sign the sequence to %s at %s", member.Addr.Hex(), member.URL)
|
| 211 |
+
signature, err := c.SignSequence(signedSequence)
|
| 212 |
+
if err != nil {
|
| 213 |
+
ch <- signatureMsg{
|
| 214 |
+
addr: member.Addr,
|
| 215 |
+
err: err,
|
| 216 |
+
}
|
| 217 |
+
return
|
| 218 |
+
}
|
| 219 |
+
// verify returned signature
|
| 220 |
+
signedSequence.Signature = signature
|
| 221 |
+
signer, err := signedSequence.Signer()
|
| 222 |
+
if err != nil {
|
| 223 |
+
ch <- signatureMsg{
|
| 224 |
+
addr: member.Addr,
|
| 225 |
+
err: err,
|
| 226 |
+
}
|
| 227 |
+
return
|
| 228 |
+
}
|
| 229 |
+
if signer != member.Addr {
|
| 230 |
+
ch <- signatureMsg{
|
| 231 |
+
addr: member.Addr,
|
| 232 |
+
err: fmt.Errorf("invalid signer. Expected %s, actual %s", member.Addr.Hex(), signer.Hex()),
|
| 233 |
+
}
|
| 234 |
+
return
|
| 235 |
+
}
|
| 236 |
+
ch <- signatureMsg{
|
| 237 |
+
addr: member.Addr,
|
| 238 |
+
signature: signature,
|
| 239 |
+
}
|
| 240 |
+
}
|
| 241 |
+
|
| 242 |
+
func buildSignaturesAndAddrs(sigs signatureMsgs, members []DataCommitteeMember) []byte {
|
| 243 |
+
const (
|
| 244 |
+
sigLen = 65
|
| 245 |
+
addrLen = 20
|
| 246 |
+
)
|
| 247 |
+
res := make([]byte, 0, len(sigs)*sigLen+len(members)*addrLen)
|
| 248 |
+
sort.Sort(sigs)
|
| 249 |
+
for _, msg := range sigs {
|
| 250 |
+
log.Debugf("adding signature %s from %s", common.Bytes2Hex(msg.signature), msg.addr.Hex())
|
| 251 |
+
res = append(res, msg.signature...)
|
| 252 |
+
}
|
| 253 |
+
for _, member := range members {
|
| 254 |
+
log.Debugf("adding addr %s", common.Bytes2Hex(member.Addr.Bytes()))
|
| 255 |
+
res = append(res, member.Addr.Bytes()...)
|
| 256 |
+
}
|
| 257 |
+
log.Debugf("full res %s", common.Bytes2Hex(res))
|
| 258 |
+
return res
|
| 259 |
+
}
|
| 260 |
+
|
| 261 |
+
type signatureMsgs []signatureMsg
|
| 262 |
+
|
| 263 |
+
func (s signatureMsgs) Len() int { return len(s) }
|
| 264 |
+
func (s signatureMsgs) Less(i, j int) bool {
|
| 265 |
+
return strings.ToUpper(s[i].addr.Hex()) < strings.ToUpper(s[j].addr.Hex())
|
| 266 |
+
}
|
| 267 |
+
func (s signatureMsgs) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
| 268 |
+
|
| 269 |
+
// getCurrentDataCommittee return the currently registered data committee
|
| 270 |
+
func (d *DataCommitteeBackend) getCurrentDataCommittee() (*DataCommittee, error) {
|
| 271 |
+
addrsHash, err := d.dataCommitteeContract.CommitteeHash(&bind.CallOpts{Pending: false})
|
| 272 |
+
if err != nil {
|
| 273 |
+
return nil, fmt.Errorf("error getting CommitteeHash from L1 SC: %w", err)
|
| 274 |
+
}
|
| 275 |
+
reqSign, err := d.dataCommitteeContract.RequiredAmountOfSignatures(&bind.CallOpts{Pending: false})
|
| 276 |
+
if err != nil {
|
| 277 |
+
return nil, fmt.Errorf("error getting RequiredAmountOfSignatures from L1 SC: %w", err)
|
| 278 |
+
}
|
| 279 |
+
members, err := d.getCurrentDataCommitteeMembers()
|
| 280 |
+
if err != nil {
|
| 281 |
+
return nil, err
|
| 282 |
+
}
|
| 283 |
+
|
| 284 |
+
return &DataCommittee{
|
| 285 |
+
AddressesHash: common.Hash(addrsHash),
|
| 286 |
+
RequiredSignatures: reqSign.Uint64(),
|
| 287 |
+
Members: members,
|
| 288 |
+
}, nil
|
| 289 |
+
}
|
| 290 |
+
|
| 291 |
+
// getCurrentDataCommitteeMembers return the currently registered data committee members
|
| 292 |
+
func (d *DataCommitteeBackend) getCurrentDataCommitteeMembers() ([]DataCommitteeMember, error) {
|
| 293 |
+
nMembers, err := d.dataCommitteeContract.GetAmountOfMembers(&bind.CallOpts{Pending: false})
|
| 294 |
+
if err != nil {
|
| 295 |
+
return nil, fmt.Errorf("error getting GetAmountOfMembers from L1 SC: %w", err)
|
| 296 |
+
}
|
| 297 |
+
members := make([]DataCommitteeMember, 0, nMembers.Int64())
|
| 298 |
+
for i := int64(0); i < nMembers.Int64(); i++ {
|
| 299 |
+
member, err := d.dataCommitteeContract.Members(&bind.CallOpts{Pending: false}, big.NewInt(i))
|
| 300 |
+
if err != nil {
|
| 301 |
+
return nil, fmt.Errorf("error getting Members %d from L1 SC: %w", i, err)
|
| 302 |
+
}
|
| 303 |
+
members = append(members, DataCommitteeMember{
|
| 304 |
+
Addr: member.Addr,
|
| 305 |
+
URL: member.Url,
|
| 306 |
+
})
|
| 307 |
+
}
|
| 308 |
+
return members, nil
|
| 309 |
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package datacommittee
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"math/big"
|
| 5 |
+
"testing"
|
| 6 |
+
|
| 7 |
+
"github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/polygondatacommittee"
|
| 8 |
+
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 9 |
+
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
| 10 |
+
"github.com/ethereum/go-ethereum/common"
|
| 11 |
+
"github.com/ethereum/go-ethereum/core"
|
| 12 |
+
"github.com/ethereum/go-ethereum/crypto"
|
| 13 |
+
"github.com/ethereum/go-ethereum/ethclient/simulated"
|
| 14 |
+
"github.com/stretchr/testify/assert"
|
| 15 |
+
"github.com/stretchr/testify/require"
|
| 16 |
+
)
|
| 17 |
+
|
| 18 |
+
func TestUpdateDataCommitteeEvent(t *testing.T) {
|
| 19 |
+
// Set up testing environment
|
| 20 |
+
dac, ethBackend, auth, da := newTestingEnv(t)
|
| 21 |
+
|
| 22 |
+
// Update the committee
|
| 23 |
+
requiredAmountOfSignatures := big.NewInt(2)
|
| 24 |
+
URLs := []string{"1", "2", "3"}
|
| 25 |
+
addrs := []common.Address{
|
| 26 |
+
common.HexToAddress("0x1"),
|
| 27 |
+
common.HexToAddress("0x2"),
|
| 28 |
+
common.HexToAddress("0x3"),
|
| 29 |
+
}
|
| 30 |
+
addrsBytes := []byte{}
|
| 31 |
+
for _, addr := range addrs {
|
| 32 |
+
addrsBytes = append(addrsBytes, addr.Bytes()...)
|
| 33 |
+
}
|
| 34 |
+
_, err := da.SetupCommittee(auth, requiredAmountOfSignatures, URLs, addrsBytes)
|
| 35 |
+
require.NoError(t, err)
|
| 36 |
+
ethBackend.Commit()
|
| 37 |
+
|
| 38 |
+
// Assert the committee update
|
| 39 |
+
actualSetup, err := dac.getCurrentDataCommittee()
|
| 40 |
+
require.NoError(t, err)
|
| 41 |
+
expectedMembers := []DataCommitteeMember{}
|
| 42 |
+
expectedSetup := DataCommittee{
|
| 43 |
+
RequiredSignatures: uint64(len(URLs) - 1),
|
| 44 |
+
AddressesHash: crypto.Keccak256Hash(addrsBytes),
|
| 45 |
+
}
|
| 46 |
+
for i, url := range URLs {
|
| 47 |
+
expectedMembers = append(expectedMembers, DataCommitteeMember{
|
| 48 |
+
URL: url,
|
| 49 |
+
Addr: addrs[i],
|
| 50 |
+
})
|
| 51 |
+
}
|
| 52 |
+
expectedSetup.Members = expectedMembers
|
| 53 |
+
assert.Equal(t, expectedSetup, *actualSetup)
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
func init() {
|
| 57 |
+
log.Init(log.Config{
|
| 58 |
+
Level: "debug",
|
| 59 |
+
Outputs: []string{"stderr"},
|
| 60 |
+
})
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
// This function prepare the blockchain, the wallet with funds and deploy the smc
|
| 64 |
+
func newTestingEnv(t *testing.T) (
|
| 65 |
+
dac *DataCommitteeBackend,
|
| 66 |
+
ethBackend *simulated.Backend,
|
| 67 |
+
auth *bind.TransactOpts,
|
| 68 |
+
da *polygondatacommittee.Polygondatacommittee,
|
| 69 |
+
) {
|
| 70 |
+
t.Helper()
|
| 71 |
+
privateKey, err := crypto.GenerateKey()
|
| 72 |
+
if err != nil {
|
| 73 |
+
log.Fatal(err)
|
| 74 |
+
}
|
| 75 |
+
auth, err = bind.NewKeyedTransactorWithChainID(privateKey, big.NewInt(1337))
|
| 76 |
+
if err != nil {
|
| 77 |
+
log.Fatal(err)
|
| 78 |
+
}
|
| 79 |
+
dac, ethBackend, da, err = newSimulatedDacman(t, auth)
|
| 80 |
+
if err != nil {
|
| 81 |
+
log.Fatal(err)
|
| 82 |
+
}
|
| 83 |
+
return dac, ethBackend, auth, da
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
// NewSimulatedEtherman creates an etherman that uses a simulated blockchain. It's important to notice that the ChainID of the auth
|
| 87 |
+
// must be 1337. The address that holds the auth will have an initial balance of 10 ETH
|
| 88 |
+
func newSimulatedDacman(t *testing.T, auth *bind.TransactOpts) (
|
| 89 |
+
dacman *DataCommitteeBackend,
|
| 90 |
+
ethBackend *simulated.Backend,
|
| 91 |
+
da *polygondatacommittee.Polygondatacommittee,
|
| 92 |
+
err error,
|
| 93 |
+
) {
|
| 94 |
+
t.Helper()
|
| 95 |
+
if auth == nil {
|
| 96 |
+
// read only client
|
| 97 |
+
return &DataCommitteeBackend{}, nil, nil, nil
|
| 98 |
+
}
|
| 99 |
+
// 10000000 ETH in wei
|
| 100 |
+
balance, _ := new(big.Int).SetString("10000000000000000000000000", 10) //nolint:gomnd
|
| 101 |
+
address := auth.From
|
| 102 |
+
genesisAlloc := map[common.Address]core.GenesisAccount{
|
| 103 |
+
address: {
|
| 104 |
+
Balance: balance,
|
| 105 |
+
},
|
| 106 |
+
}
|
| 107 |
+
blockGasLimit := uint64(999999999999999999) //nolint:gomnd
|
| 108 |
+
client := simulated.NewBackend(genesisAlloc, simulated.WithBlockGasLimit(blockGasLimit))
|
| 109 |
+
|
| 110 |
+
// DAC Setup
|
| 111 |
+
_, _, da, err = polygondatacommittee.DeployPolygondatacommittee(auth, client.Client())
|
| 112 |
+
if err != nil {
|
| 113 |
+
return &DataCommitteeBackend{}, nil, nil, err
|
| 114 |
+
}
|
| 115 |
+
client.Commit()
|
| 116 |
+
_, err = da.Initialize(auth)
|
| 117 |
+
if err != nil {
|
| 118 |
+
return &DataCommitteeBackend{}, nil, nil, err
|
| 119 |
+
}
|
| 120 |
+
client.Commit()
|
| 121 |
+
_, err = da.SetupCommittee(auth, big.NewInt(0), []string{}, []byte{})
|
| 122 |
+
if err != nil {
|
| 123 |
+
return &DataCommitteeBackend{}, nil, nil, err
|
| 124 |
+
}
|
| 125 |
+
client.Commit()
|
| 126 |
+
|
| 127 |
+
c := &DataCommitteeBackend{
|
| 128 |
+
dataCommitteeContract: da,
|
| 129 |
+
}
|
| 130 |
+
return c, client, da, nil
|
| 131 |
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package dataavailability
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"context"
|
| 5 |
+
"math/big"
|
| 6 |
+
|
| 7 |
+
"github.com/0xPolygonHermez/zkevm-node/jsonrpc/types"
|
| 8 |
+
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 9 |
+
"github.com/ethereum/go-ethereum/common"
|
| 10 |
+
"github.com/jackc/pgx/v4"
|
| 11 |
+
)
|
| 12 |
+
|
| 13 |
+
// DABackender is an interface for components that store and retrieve batch data
|
| 14 |
+
type DABackender interface {
|
| 15 |
+
SequenceRetriever
|
| 16 |
+
SequenceSender
|
| 17 |
+
// Init initializes the DABackend
|
| 18 |
+
Init() error
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
// SequenceSender is used to send provided sequence of batches
|
| 22 |
+
type SequenceSender interface {
|
| 23 |
+
// PostSequence sends the sequence data to the data availability backend, and returns the dataAvailabilityMessage
|
| 24 |
+
// as expected by the contract
|
| 25 |
+
PostSequence(ctx context.Context, batchesData [][]byte) ([]byte, error)
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
// SequenceRetriever is used to retrieve batch data
|
| 29 |
+
type SequenceRetriever interface {
|
| 30 |
+
// GetSequence retrieves the sequence data from the data availability backend
|
| 31 |
+
GetSequence(ctx context.Context, batchHashes []common.Hash, dataAvailabilityMessage []byte) ([][]byte, error)
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
// === Internal interfaces ===
|
| 35 |
+
|
| 36 |
+
type stateInterface interface {
|
| 37 |
+
GetBatchL2DataByNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) ([]byte, error)
|
| 38 |
+
GetBatchL2DataByNumbers(ctx context.Context, batchNumbers []uint64, dbTx pgx.Tx) (map[uint64][]byte, error)
|
| 39 |
+
GetBatchByNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.Batch, error)
|
| 40 |
+
GetForcedBatchDataByNumbers(ctx context.Context, batchNumbers []uint64, dbTx pgx.Tx) (map[uint64][]byte, error)
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
// BatchDataProvider is used to retrieve batch data
|
| 44 |
+
type BatchDataProvider interface {
|
| 45 |
+
// GetBatchL2Data retrieve the data of a batch from the DA backend. The returned data must be the pre-image of the hash
|
| 46 |
+
GetBatchL2Data(batchNum []uint64, batchHashes []common.Hash, dataAvailabilityMessage []byte) ([][]byte, error)
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
// DataManager is an interface for components that send and retrieve batch data
|
| 50 |
+
type DataManager interface {
|
| 51 |
+
BatchDataProvider
|
| 52 |
+
SequenceSender
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
// ZKEVMClientTrustedBatchesGetter contains the methods required to interact with zkEVM-RPC
|
| 56 |
+
type ZKEVMClientTrustedBatchesGetter interface {
|
| 57 |
+
BatchByNumber(ctx context.Context, number *big.Int) (*types.Batch, error)
|
| 58 |
+
BatchesByNumbers(ctx context.Context, numbers []*big.Int) ([]*types.BatchData, error)
|
| 59 |
+
ForcedBatchesByNumbers(ctx context.Context, numbers []*big.Int) ([]*types.BatchData, error)
|
| 60 |
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
-- +migrate Down
|
| 2 |
+
DROP TABLE IF EXISTS pool.acl CASCADE;
|
| 3 |
+
DROP TABLE IF EXISTS pool.policy CASCADE;
|
| 4 |
+
|
| 5 |
+
-- +migrate Up
|
| 6 |
+
CREATE TABLE pool.policy
|
| 7 |
+
(
|
| 8 |
+
name VARCHAR PRIMARY KEY,
|
| 9 |
+
allow BOOLEAN NOT NULL DEFAULT false
|
| 10 |
+
);
|
| 11 |
+
|
| 12 |
+
INSERT INTO pool.policy (name, allow) VALUES ('send_tx', false);
|
| 13 |
+
INSERT INTO pool.policy (name, allow) VALUES ('deploy', false);
|
| 14 |
+
|
| 15 |
+
CREATE TABLE pool.acl
|
| 16 |
+
(
|
| 17 |
+
address VARCHAR,
|
| 18 |
+
policy VARCHAR,
|
| 19 |
+
PRIMARY KEY (address, policy)
|
| 20 |
+
);
|
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
-- +migrate Up
|
| 2 |
+
ALTER TABLE state.block
|
| 3 |
+
ADD COLUMN IF NOT EXISTS checked BOOL NOT NULL DEFAULT FALSE;
|
| 4 |
+
|
| 5 |
+
-- set block.checked to true for all blocks below max - 100
|
| 6 |
+
UPDATE state.block SET checked = true WHERE block_num <= (SELECT MAX(block_num) - 1000 FROM state.block);
|
| 7 |
+
|
| 8 |
+
-- +migrate Down
|
| 9 |
+
ALTER TABLE state.block
|
| 10 |
+
DROP COLUMN IF EXISTS checked;
|
| 11 |
+
|
|
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package migrations_test
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"database/sql"
|
| 5 |
+
"testing"
|
| 6 |
+
"time"
|
| 7 |
+
|
| 8 |
+
"github.com/stretchr/testify/assert"
|
| 9 |
+
)
|
| 10 |
+
|
| 11 |
+
type migrationTest0018 struct{}
|
| 12 |
+
|
| 13 |
+
func (m migrationTest0018) InsertData(db *sql.DB) error {
|
| 14 |
+
const addBlock = "INSERT INTO state.block (block_num, received_at, block_hash) VALUES ($1, $2, $3)"
|
| 15 |
+
if _, err := db.Exec(addBlock, 1, time.Now(), "0x29e885edaf8e4b51e1d2e05f9da28161d2fb4f6b1d53827d9b80a23cf2d7d9f1"); err != nil {
|
| 16 |
+
return err
|
| 17 |
+
}
|
| 18 |
+
if _, err := db.Exec(addBlock, 50, time.Now(), "0x29e885edaf8e4b51e1d2e05f9da28161d2fb4f6b1d53827d9b80a23cf2d7d9f1"); err != nil {
|
| 19 |
+
return err
|
| 20 |
+
}
|
| 21 |
+
if _, err := db.Exec(addBlock, 1050, time.Now(), "0x29e885edaf8e4b51e1d2e05f9da28161d2fb4f6b1d53827d9b80a23cf2d7d9f1"); err != nil {
|
| 22 |
+
return err
|
| 23 |
+
}
|
| 24 |
+
return nil
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
func (m migrationTest0018) RunAssertsAfterMigrationUp(t *testing.T, db *sql.DB) {
|
| 28 |
+
var checked bool
|
| 29 |
+
row := db.QueryRow("SELECT checked FROM state.block WHERE block_num = $1", 1)
|
| 30 |
+
assert.NoError(t, row.Scan(&checked))
|
| 31 |
+
assert.Equal(t, true, checked)
|
| 32 |
+
row = db.QueryRow("SELECT checked FROM state.block WHERE block_num = $1", 50)
|
| 33 |
+
assert.NoError(t, row.Scan(&checked))
|
| 34 |
+
assert.Equal(t, true, checked)
|
| 35 |
+
row = db.QueryRow("SELECT checked FROM state.block WHERE block_num = $1", 1050)
|
| 36 |
+
assert.NoError(t, row.Scan(&checked))
|
| 37 |
+
assert.Equal(t, false, checked)
|
| 38 |
+
|
| 39 |
+
const addBlock = "INSERT INTO state.block (block_num, received_at, block_hash, checked) VALUES ($1, $2, $3, $4)"
|
| 40 |
+
_, err := db.Exec(addBlock, 2, time.Now(), "0x29e885edaf8e4b51e1d2e05f9da28161d2fb4f6b1d53827d9b80a23cf2d7d9f1", true)
|
| 41 |
+
assert.NoError(t, err)
|
| 42 |
+
_, err = db.Exec(addBlock, 3, time.Now(), "0x29e885edaf8e4b51e1d2e05f9da28161d2fb4f6b1d53827d9b80a23cf2d7d9f1", false)
|
| 43 |
+
assert.NoError(t, err)
|
| 44 |
+
const sql = `SELECT count(*) FROM state.block WHERE checked = true`
|
| 45 |
+
row = db.QueryRow(sql)
|
| 46 |
+
var result int
|
| 47 |
+
assert.NoError(t, row.Scan(&result))
|
| 48 |
+
assert.Equal(t, 3, result, "must be 1,50 per migration and 2 by insert")
|
| 49 |
+
|
| 50 |
+
const sqlCheckedFalse = `SELECT count(*) FROM state.block WHERE checked = false`
|
| 51 |
+
row = db.QueryRow(sqlCheckedFalse)
|
| 52 |
+
|
| 53 |
+
assert.NoError(t, row.Scan(&result))
|
| 54 |
+
assert.Equal(t, 2, result, "must be 150 by migration, and 3 by insert")
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
func (m migrationTest0018) RunAssertsAfterMigrationDown(t *testing.T, db *sql.DB) {
|
| 58 |
+
var result int
|
| 59 |
+
|
| 60 |
+
// Check column wip doesn't exists in state.batch table
|
| 61 |
+
const sql = `SELECT count(*) FROM state.block`
|
| 62 |
+
row := db.QueryRow(sql)
|
| 63 |
+
assert.NoError(t, row.Scan(&result))
|
| 64 |
+
assert.Equal(t, 5, result)
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
func TestMigration0018(t *testing.T) {
|
| 68 |
+
runMigrationTest(t, 18, migrationTest0018{})
|
| 69 |
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
-- +migrate Up
|
| 2 |
+
|
| 3 |
+
-- the update below fix the wrong receipt TX indexes
|
| 4 |
+
WITH map_fix_tx_index AS (
|
| 5 |
+
SELECT t.l2_block_num AS block_num
|
| 6 |
+
, t.hash AS tx_hash
|
| 7 |
+
, r.tx_index AS current_index
|
| 8 |
+
, (ROW_NUMBER() OVER (PARTITION BY t.l2_block_num ORDER BY r.tx_index))-1 AS correct_index
|
| 9 |
+
FROM state.receipt r
|
| 10 |
+
INNER JOIN state."transaction" t
|
| 11 |
+
ON t.hash = r.tx_hash
|
| 12 |
+
)
|
| 13 |
+
UPDATE state.receipt AS r
|
| 14 |
+
SET tx_index = m.correct_index
|
| 15 |
+
FROM map_fix_tx_index m
|
| 16 |
+
WHERE m.block_num = r.block_num
|
| 17 |
+
AND m.tx_hash = r.tx_hash
|
| 18 |
+
AND m.current_index = r.tx_index
|
| 19 |
+
AND m.current_index != m.correct_index;
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
-- +migrate Down
|
| 23 |
+
|
| 24 |
+
-- no action is needed, the data fixed by the
|
| 25 |
+
-- migrate up must remain fixed
|
|
@@ -0,0 +1,145 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package migrations_test
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"database/sql"
|
| 5 |
+
"testing"
|
| 6 |
+
|
| 7 |
+
"github.com/0xPolygonHermez/zkevm-node/hex"
|
| 8 |
+
"github.com/ethereum/go-ethereum/common"
|
| 9 |
+
"github.com/stretchr/testify/require"
|
| 10 |
+
)
|
| 11 |
+
|
| 12 |
+
type migrationTest0019TestCase struct {
|
| 13 |
+
Name string
|
| 14 |
+
Block migrationTest0019TestCaseBlock
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
type migrationTest0019TestCaseBlock struct {
|
| 18 |
+
Transactions []migrationTest0019TestCaseTransaction
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
type migrationTest0019TestCaseTransaction struct {
|
| 22 |
+
CurrentIndex uint
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
type migrationTest0019 struct {
|
| 26 |
+
TestCases []migrationTest0019TestCase
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
func (m migrationTest0019) InsertData(db *sql.DB) error {
|
| 30 |
+
const addBlock0 = "INSERT INTO state.block (block_num, received_at, block_hash) VALUES (0, now(), '0x0')"
|
| 31 |
+
if _, err := db.Exec(addBlock0); err != nil {
|
| 32 |
+
return err
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
const addBatch0 = `
|
| 36 |
+
INSERT INTO state.batch (batch_num, global_exit_root, local_exit_root, acc_input_hash, state_root, timestamp, coinbase, raw_txs_data, forced_batch_num, wip)
|
| 37 |
+
VALUES (0,'0x0000', '0x0000', '0x0000', '0x0000', now(), '0x0000', null, null, true)`
|
| 38 |
+
if _, err := db.Exec(addBatch0); err != nil {
|
| 39 |
+
return err
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
const addL2Block = "INSERT INTO state.l2block (block_num, block_hash, header, uncles, parent_hash, state_root, received_at, batch_num, created_at) VALUES ($1, $2, '{}', '{}', '0x0', '0x0', now(), 0, now())"
|
| 43 |
+
const addTransaction = "INSERT INTO state.transaction (hash, encoded, decoded, l2_block_num, effective_percentage, l2_hash) VALUES ($1, 'ABCDEF', '{}', $2, 255, $1)"
|
| 44 |
+
const addReceipt = "INSERT INTO state.receipt (tx_hash, type, post_state, status, cumulative_gas_used, gas_used, effective_gas_price, block_num, tx_index, contract_address) VALUES ($1, 1, null, 1, 1234, 1234, 1, $2, $3, '')"
|
| 45 |
+
|
| 46 |
+
txUnique := 0
|
| 47 |
+
for tci, testCase := range m.TestCases {
|
| 48 |
+
blockNum := uint64(tci + 1)
|
| 49 |
+
blockHash := common.HexToHash(hex.EncodeUint64(blockNum)).String()
|
| 50 |
+
if _, err := db.Exec(addL2Block, blockNum, blockHash); err != nil {
|
| 51 |
+
return err
|
| 52 |
+
}
|
| 53 |
+
for _, tx := range testCase.Block.Transactions {
|
| 54 |
+
txUnique++
|
| 55 |
+
txHash := common.HexToHash(hex.EncodeUint64(uint64(txUnique))).String()
|
| 56 |
+
if _, err := db.Exec(addTransaction, txHash, blockNum); err != nil {
|
| 57 |
+
return err
|
| 58 |
+
}
|
| 59 |
+
if _, err := db.Exec(addReceipt, txHash, blockNum, tx.CurrentIndex); err != nil {
|
| 60 |
+
return err
|
| 61 |
+
}
|
| 62 |
+
}
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
return nil
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
func (m migrationTest0019) RunAssertsAfterMigrationUp(t *testing.T, db *sql.DB) {
|
| 69 |
+
const getReceiptsByBlock = "SELECT r.tx_index FROM state.receipt r WHERE r.block_num = $1 ORDER BY r.tx_index"
|
| 70 |
+
|
| 71 |
+
for tci := range m.TestCases {
|
| 72 |
+
blockNum := uint64(tci + 1)
|
| 73 |
+
|
| 74 |
+
rows, err := db.Query(getReceiptsByBlock, blockNum)
|
| 75 |
+
require.NoError(t, err)
|
| 76 |
+
|
| 77 |
+
var expectedIndex = uint(0)
|
| 78 |
+
var txIndex uint
|
| 79 |
+
for rows.Next() {
|
| 80 |
+
err := rows.Scan(&txIndex)
|
| 81 |
+
require.NoError(t, err)
|
| 82 |
+
require.Equal(t, expectedIndex, txIndex)
|
| 83 |
+
expectedIndex++
|
| 84 |
+
}
|
| 85 |
+
}
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
func (m migrationTest0019) RunAssertsAfterMigrationDown(t *testing.T, db *sql.DB) {
|
| 89 |
+
m.RunAssertsAfterMigrationUp(t, db)
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
func TestMigration0019(t *testing.T) {
|
| 93 |
+
runMigrationTest(t, 19, migrationTest0019{
|
| 94 |
+
TestCases: []migrationTest0019TestCase{
|
| 95 |
+
{
|
| 96 |
+
Name: "single tx with correct index",
|
| 97 |
+
Block: migrationTest0019TestCaseBlock{
|
| 98 |
+
Transactions: []migrationTest0019TestCaseTransaction{
|
| 99 |
+
{CurrentIndex: 0},
|
| 100 |
+
},
|
| 101 |
+
},
|
| 102 |
+
},
|
| 103 |
+
{
|
| 104 |
+
Name: "multiple txs indexes are correct",
|
| 105 |
+
Block: migrationTest0019TestCaseBlock{
|
| 106 |
+
Transactions: []migrationTest0019TestCaseTransaction{
|
| 107 |
+
{CurrentIndex: 0},
|
| 108 |
+
{CurrentIndex: 1},
|
| 109 |
+
{CurrentIndex: 2},
|
| 110 |
+
},
|
| 111 |
+
},
|
| 112 |
+
},
|
| 113 |
+
{
|
| 114 |
+
Name: "single tx with wrong tx index",
|
| 115 |
+
Block: migrationTest0019TestCaseBlock{
|
| 116 |
+
Transactions: []migrationTest0019TestCaseTransaction{
|
| 117 |
+
{CurrentIndex: 3},
|
| 118 |
+
},
|
| 119 |
+
},
|
| 120 |
+
},
|
| 121 |
+
{
|
| 122 |
+
Name: "multiple txs missing 0 index",
|
| 123 |
+
Block: migrationTest0019TestCaseBlock{
|
| 124 |
+
Transactions: []migrationTest0019TestCaseTransaction{
|
| 125 |
+
{CurrentIndex: 1},
|
| 126 |
+
{CurrentIndex: 2},
|
| 127 |
+
{CurrentIndex: 3},
|
| 128 |
+
{CurrentIndex: 4},
|
| 129 |
+
},
|
| 130 |
+
},
|
| 131 |
+
},
|
| 132 |
+
{
|
| 133 |
+
Name: "multiple has index 0 but also txs index gap",
|
| 134 |
+
Block: migrationTest0019TestCaseBlock{
|
| 135 |
+
Transactions: []migrationTest0019TestCaseTransaction{
|
| 136 |
+
{CurrentIndex: 0},
|
| 137 |
+
{CurrentIndex: 2},
|
| 138 |
+
{CurrentIndex: 4},
|
| 139 |
+
{CurrentIndex: 6},
|
| 140 |
+
},
|
| 141 |
+
},
|
| 142 |
+
},
|
| 143 |
+
},
|
| 144 |
+
})
|
| 145 |
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
-- +migrate Up
|
| 2 |
+
|
| 3 |
+
-- This migration will delete all empty blocks
|
| 4 |
+
DELETE FROM state.block
|
| 5 |
+
WHERE NOT EXISTS (SELECT *
|
| 6 |
+
FROM state.virtual_batch
|
| 7 |
+
WHERE state.virtual_batch.block_num = state.block.block_num)
|
| 8 |
+
AND NOT EXISTS (SELECT *
|
| 9 |
+
FROM state.verified_batch
|
| 10 |
+
WHERE state.verified_batch.block_num = state.block.block_num)
|
| 11 |
+
AND NOT EXISTS (SELECT *
|
| 12 |
+
FROM state.forced_batch
|
| 13 |
+
WHERE state.forced_batch.block_num = state.block.block_num)
|
| 14 |
+
AND NOT EXISTS (SELECT *
|
| 15 |
+
FROM state.exit_root
|
| 16 |
+
WHERE state.exit_root.block_num = state.block.block_num)
|
| 17 |
+
AND NOT EXISTS (SELECT *
|
| 18 |
+
FROM state.monitored_txs
|
| 19 |
+
WHERE state.monitored_txs.block_num = state.block.block_num)
|
| 20 |
+
AND NOT EXISTS (SELECT *
|
| 21 |
+
FROM state.fork_id
|
| 22 |
+
WHERE state.fork_id.block_num = state.block.block_num);
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
-- +migrate Down
|
| 27 |
+
|
| 28 |
+
-- no action is needed, the data must remain deleted as it is useless
|
|
@@ -0,0 +1,99 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package migrations_test
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"database/sql"
|
| 5 |
+
"fmt"
|
| 6 |
+
"testing"
|
| 7 |
+
|
| 8 |
+
"github.com/stretchr/testify/assert"
|
| 9 |
+
)
|
| 10 |
+
|
| 11 |
+
// this migration changes length of the token name
|
| 12 |
+
type migrationTest0020 struct{}
|
| 13 |
+
|
| 14 |
+
func (m migrationTest0020) InsertData(db *sql.DB) error {
|
| 15 |
+
addBlocks := `
|
| 16 |
+
INSERT INTO state.block
|
| 17 |
+
(block_num, block_hash, parent_hash, received_at, checked)
|
| 18 |
+
VALUES(1, '0x013be63487a53c874614dd1ae0434cf211e393b2e386c8fde74da203b5469b20', '0x0328698ebeda498df8c63040e2a4771d24722ab2c1e8291226b9215c7eec50fe', '2024-03-11 02:52:23.000', true);
|
| 19 |
+
INSERT INTO state.block
|
| 20 |
+
(block_num, block_hash, parent_hash, received_at, checked)
|
| 21 |
+
VALUES(2, '0x013be63487a53c874614dd1ae0434cf211e393b2e386c8fde74da203b5469b21', '0x0328698ebeda498df8c63040e2a4771d24722ab2c1e8291226b9215c7eec50f1', '2024-03-11 02:52:24.000', true);
|
| 22 |
+
INSERT INTO state.block
|
| 23 |
+
(block_num, block_hash, parent_hash, received_at, checked)
|
| 24 |
+
VALUES(3, '0x013be63487a53c874614dd1ae0434cf211e393b2e386c8fde74da203b5469b22', '0x0328698ebeda498df8c63040e2a4771d24722ab2c1e8291226b9215c7eec50f2', '2024-03-11 02:52:25.000', false);
|
| 25 |
+
INSERT INTO state.block
|
| 26 |
+
(block_num, block_hash, parent_hash, received_at, checked)
|
| 27 |
+
VALUES(4, '0x013be63487a53c874614dd1ae0434cf211e393b2e386c8fde74da203b5469b23', '0x0328698ebeda498df8c63040e2a4771d24722ab2c1e8291226b9215c7eec50f3', '2024-03-11 02:52:26.000', false);
|
| 28 |
+
INSERT INTO state.block
|
| 29 |
+
(block_num, block_hash, parent_hash, received_at, checked)
|
| 30 |
+
VALUES(5, '0x013be63487a53c874614dd1ae0434cf211e393b2e386c8fde74da203b5469b24', '0x0328698ebeda498df8c63040e2a4771d24722ab2c1e8291226b9215c7eec50f4', '2024-03-11 02:52:27.000', true);
|
| 31 |
+
INSERT INTO state.block
|
| 32 |
+
(block_num, block_hash, parent_hash, received_at, checked)
|
| 33 |
+
VALUES(6, '0x013be63487a53c874614dd1ae0434cf211e393b2e386c8fde74da203b5469b25', '0x0328698ebeda498df8c63040e2a4771d24722ab2c1e8291226b9215c7eec50f5', '2024-03-11 02:52:28.000', true);
|
| 34 |
+
INSERT INTO state.block
|
| 35 |
+
(block_num, block_hash, parent_hash, received_at, checked)
|
| 36 |
+
VALUES(7, '0x013be63487a53c874614dd1ae0434cf211e393b2e386c8fde74da203b5469b26', '0x0328698ebeda498df8c63040e2a4771d24722ab2c1e8291226b9215c7eec50f6', '2024-03-11 02:52:29.000', true);
|
| 37 |
+
INSERT INTO state.block
|
| 38 |
+
(block_num, block_hash, parent_hash, received_at, checked)
|
| 39 |
+
VALUES(8, '0x013be63487a53c874614dd1ae0434cf211e393b2e386c8fde74da203b5469b27', '0x0328698ebeda498df8c63040e2a4771d24722ab2c1e8291226b9215c7eec50f7', '2024-03-11 02:52:30.000', true);
|
| 40 |
+
INSERT INTO state.block
|
| 41 |
+
(block_num, block_hash, parent_hash, received_at, checked)
|
| 42 |
+
VALUES(9, '0x013be63487a53c874614dd1ae0434cf211e393b2e386c8fde74da203b5469b28', '0x0328698ebeda498df8c63040e2a4771d24722ab2c1e8291226b9215c7eec50f8', '2024-03-11 02:52:31.000', true);
|
| 43 |
+
INSERT INTO state.block
|
| 44 |
+
(block_num, block_hash, parent_hash, received_at, checked)
|
| 45 |
+
VALUES(10, '0x013be63487a53c874614dd1ae0434cf211e393b2e386c8fde74da203b5469b29', '0x0328698ebeda498df8c63040e2a4771d24722ab2c1e8291226b9215c7eec50f9', '2024-03-11 02:52:32.000', true);
|
| 46 |
+
INSERT INTO state.block
|
| 47 |
+
(block_num, block_hash, parent_hash, received_at, checked)
|
| 48 |
+
VALUES(11, '0x013be63487a53c874614dd1ae0434cf211e393b2e386c8fde74da203b5469b2a', '0x0328698ebeda498df8c63040e2a4771d24722ab2c1e8291226b9215c7eec50fa', '2024-03-11 02:52:33.000', true);
|
| 49 |
+
INSERT INTO state.batch
|
| 50 |
+
(batch_num, global_exit_root, local_exit_root, state_root, acc_input_hash, "timestamp", coinbase, raw_txs_data, forced_batch_num, batch_resources, closing_reason, wip, checked)
|
| 51 |
+
VALUES(1, '0x0000000000000000000000000000000000000000000000000000000000000000', '0x0000000000000000000000000000000000000000000000000000000000000000', '0x3f86b09b43e3e49a41fc20a07579b79eba044253367817d5c241d23c0e2bc5c9', '0xa5bd7311fe00707809dd3aa718be2ea0cb363626b9db44172098515f07acf940', '2023-03-24 16:35:27.000', '0x148Ee7dAF16574cD020aFa34CC658f8F3fbd2800', decode('','hex'), NULL, '{"Bytes": 0, "ZKCounters": {"GasUsed": 0, "UsedSteps": 0, "UsedBinaries": 0, "UsedMemAligns": 0, "UsedArithmetics": 0, "UsedKeccakHashes": 0, "UsedPoseidonHashes": 0, "UsedSha256Hashes_V2": 0, "UsedPoseidonPaddings": 0}}'::jsonb, '', false, true);
|
| 52 |
+
INSERT INTO state.virtual_batch
|
| 53 |
+
(batch_num, tx_hash, coinbase, block_num, sequencer_addr, timestamp_batch_etrog, l1_info_root)
|
| 54 |
+
VALUES(1, '0x4314ed5d8ad4812e88895942b2b4642af176d80a97c5489a16a7a5aeb08b51a6', '0x148Ee7dAF16574cD020aFa34CC658f8F3fbd2800', 2, '0x148Ee7dAF16574cD020aFa34CC658f8F3fbd2800', '2024-04-09 16:26:45.000', '0xcdb4258d7ccd8fd41c4a26fd8d9d1fadbc9c506e64d489170525a65e2ad3580b');
|
| 55 |
+
INSERT INTO state.verified_batch
|
| 56 |
+
(batch_num, tx_hash, aggregator, state_root, block_num, is_trusted)
|
| 57 |
+
VALUES(1, '0x28e82f15ab7bac043598623c65a838c315d00ecb5d6e013c406d6bb889680592', '0x6329Fe417621925C81c16F9F9a18c203C21Af7ab', '0x80bd488b1e150b9b42611d038c7fdfa43a3e95b3a02e5c2d57074e73b583f8fd', 3, true);
|
| 58 |
+
INSERT INTO state.fork_id
|
| 59 |
+
(fork_id, from_batch_num, to_batch_num, "version", block_num)
|
| 60 |
+
VALUES(5, 813267, 1228916, 'v2.0.0-RC1-fork.5', 5);
|
| 61 |
+
INSERT INTO state.monitored_txs
|
| 62 |
+
("owner", id, from_addr, to_addr, nonce, value, "data", gas, gas_price, status, history, block_num, created_at, updated_at, gas_offset)
|
| 63 |
+
VALUES('sequencer', 'sequence-from-2006249-to-2006252', '0x148Ee7dAF16574cD020aFa34CC658f8F3fbd2800', '0x519E42c24163192Dca44CD3fBDCEBF6be9130987', 58056, NULL, 'def57e540000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000006614ec3100000000000000000000000000000000000000000000000000000000001e9ce8000000000000000000000000148ee7da0000000300000000ee8306089a84ae0baa0082520894417a7ba2d8d0060ae6c54fd098590db854b9c1d58609184e72a0008082044d80802787e068e6fe23cda64eb868cefb7231a17449d508a77919f6c5408814aaab5f259d43a62eb50df0b2d5740552d3f95176a1f0e31cade590facf70b01c1129151bab0b00000003000000000b00000003000000000b00000003000000000b00000003000000000b0000000300000000000000000000000000000000000000', 1474265, 25212431373, 'done', '{0x44423d538d6fc2f2e882fcd0d1952a735d81c824827b83936e6a5e52268a7d8e}', 7, '2024-04-09 09:26:36.235', '2024-04-09 09:38:24.377', 150000);
|
| 64 |
+
INSERT INTO state.exit_root
|
| 65 |
+
(id, block_num, "timestamp", mainnet_exit_root, rollup_exit_root, global_exit_root, prev_block_hash, l1_info_root, l1_info_tree_index)
|
| 66 |
+
VALUES(379599, 8, '2024-04-09 09:43:59.000', decode('C90DCBC69719971625800AD619E5EEEFD0378317E26F0DDE9B30B3C7C84DBD78','hex'), decode('514D72BBF7C2AD8E4D15EC1186EBF077E98208479651B1C30C5AC7DA11BAB209','hex'), decode('B20FACBED4A2774CE33A0F68D9B6F9B4D9AD553DACD73705503910B141D2102E','hex'), decode('845E01F723E5C77DBE5A4889F299860FBECD8353BFD423D366851F3A90496334','hex'), decode('EDB0EF9C80E947C411FD9B8B23318708132F8A3BD15CD366499866EF91748FC8','hex'), 8032);
|
| 67 |
+
INSERT INTO state.forced_batch
|
| 68 |
+
(block_num, forced_batch_num, global_exit_root, timestamp, raw_txs_data, coinbase)
|
| 69 |
+
VALUES(10, 1, '0x3f86b09b43e3e49a41fc20a07579b79eba044253367817d5c241d23c0e2bc5ca', '2024-04-09 09:26:36.235', '0x3f86b09b', '0x3f86b09b43e3e49a41fc20a07579b79eba044253367817d5c241d23c0e2bc5c9');
|
| 70 |
+
`
|
| 71 |
+
if _, err := db.Exec(addBlocks); err != nil {
|
| 72 |
+
return err
|
| 73 |
+
}
|
| 74 |
+
blockCount := `SELECT count(*) FROM state.block`
|
| 75 |
+
var count int
|
| 76 |
+
err := db.QueryRow(blockCount).Scan(&count)
|
| 77 |
+
if err != nil {
|
| 78 |
+
return err
|
| 79 |
+
}
|
| 80 |
+
if count != 11 {
|
| 81 |
+
return fmt.Errorf("error: initial wrong number of blocks")
|
| 82 |
+
}
|
| 83 |
+
return nil
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
func (m migrationTest0020) RunAssertsAfterMigrationUp(t *testing.T, db *sql.DB) {
|
| 87 |
+
blockCount := `SELECT count(*) FROM state.block`
|
| 88 |
+
var count int
|
| 89 |
+
err := db.QueryRow(blockCount).Scan(&count)
|
| 90 |
+
assert.NoError(t, err)
|
| 91 |
+
assert.Equal(t, 6, count)
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
func (m migrationTest0020) RunAssertsAfterMigrationDown(t *testing.T, db *sql.DB) {
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
func TestMigration0020(t *testing.T) {
|
| 98 |
+
runMigrationTest(t, 20, migrationTest0020{})
|
| 99 |
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
-- +migrate Up
|
| 2 |
+
|
| 3 |
+
CREATE TABLE IF NOT EXISTS state.batch_data_backup
|
| 4 |
+
(
|
| 5 |
+
batch_num BIGINT,
|
| 6 |
+
data BYTEA,
|
| 7 |
+
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 8 |
+
PRIMARY KEY (batch_num, created_at)
|
| 9 |
+
);
|
| 10 |
+
|
| 11 |
+
-- +migrate StatementBegin
|
| 12 |
+
CREATE OR REPLACE FUNCTION backup_batch() RETURNS trigger AS $$
|
| 13 |
+
BEGIN
|
| 14 |
+
INSERT INTO state.batch_data_backup (batch_num, data)
|
| 15 |
+
VALUES (OLD.batch_num, OLD.raw_txs_data)
|
| 16 |
+
ON CONFLICT (batch_num, created_at) DO UPDATE SET
|
| 17 |
+
data = EXCLUDED.data;
|
| 18 |
+
RETURN OLD;
|
| 19 |
+
END;
|
| 20 |
+
$$
|
| 21 |
+
LANGUAGE plpgsql;
|
| 22 |
+
-- +migrate StatementEnd
|
| 23 |
+
|
| 24 |
+
CREATE TRIGGER backup_batch
|
| 25 |
+
BEFORE DELETE ON state.batch FOR EACH ROW
|
| 26 |
+
EXECUTE PROCEDURE backup_batch();
|
| 27 |
+
|
| 28 |
+
-- +migrate Down
|
| 29 |
+
|
| 30 |
+
DROP TRIGGER IF EXISTS backup_batch ON state.batch;
|
| 31 |
+
DROP FUNCTION IF EXISTS backup_batch();
|
| 32 |
+
DROP TABLE IF EXISTS state.batch_data_backup;
|
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
PATH_TO_ZKEVM_NODE_REPO="/home/stefan/go/src/Polygon/zkevm-node/"
|
| 2 |
+
diff -ruN \
|
| 3 |
+
-I ".*github.com\/0x.*" \
|
| 4 |
+
-x "*mock*" -x ".git" \
|
| 5 |
+
-x ".github" \
|
| 6 |
+
-x ".gitignore" \
|
| 7 |
+
-x ".vscode" \
|
| 8 |
+
-x "ci" \
|
| 9 |
+
-x "environments" \
|
| 10 |
+
-x "*.md" \
|
| 11 |
+
-x "*.html" \
|
| 12 |
+
-x "*.html" \
|
| 13 |
+
-x "*.json" \
|
| 14 |
+
-x "*.toml" \
|
| 15 |
+
-x "*.abi" \
|
| 16 |
+
-x "*.bin" \
|
| 17 |
+
-x "*.pb.go" \
|
| 18 |
+
-x "smartcontracts" \
|
| 19 |
+
-x "go.sum" \
|
| 20 |
+
-x "mock*.go" \
|
| 21 |
+
-x "*venv*" \
|
| 22 |
+
-x "/dist/" \
|
| 23 |
+
-x "/test/e2e/keystore" \
|
| 24 |
+
-x "/test/vectors/src/**/*md" \
|
| 25 |
+
-x "/test/vectors/src/**/*js" \
|
| 26 |
+
-x "/test/vectors/src/**/*sol" \
|
| 27 |
+
-x "/test/vectors/src/**/*sh" \
|
| 28 |
+
-x "/test/vectors/src/package.json" \
|
| 29 |
+
-x "/test/contracts/bin/**/*.bin" \
|
| 30 |
+
-x "/test/contracts/bin/**/*.abi" \
|
| 31 |
+
-x "/tools/datastreamer/*.bin" \
|
| 32 |
+
-x "/test/datastreamer/*.db/*" \
|
| 33 |
+
-x "/test/*.bin" \
|
| 34 |
+
-x "/test/*.db/*" \
|
| 35 |
+
-x "**/.DS_Store" \
|
| 36 |
+
-x ".vscode" \
|
| 37 |
+
-x ".idea/" \
|
| 38 |
+
-x ".env" \
|
| 39 |
+
-x "out.dat" \
|
| 40 |
+
-x "cmd/__debug_bin" \
|
| 41 |
+
-x ".venv" \
|
| 42 |
+
-x "*metrics.txt" \
|
| 43 |
+
-x "coverage.out" \
|
| 44 |
+
-x "*datastream.db*" \
|
| 45 |
+
${PATH_TO_ZKEVM_NODE_REPO} . | \
|
| 46 |
+
diff2html -i stdin -s side -t "zkEVM node vs CDK validium node</br><h2>zkevm-node version: v0.6.0<h2/>" \
|
| 47 |
+
-F ./docs/diff/diff.html
|
|
@@ -14,7 +14,6 @@
|
|
| 14 |
# CONTAINER FOR RUNNING BINARY
|
| 15 |
FROM alpine:3.18
|
| 16 |
COPY --from=build /src/dist/zkevm-node /app/zkevm-node
|
| 17 |
-
COPY --from=build /src/config/environments/testnet/node.config.toml /app/example.config.toml
|
| 18 |
RUN apk update && apk add postgresql15-client
|
| 19 |
EXPOSE 8123
|
| 20 |
CMD ["/bin/sh", "-c", "/app/zkevm-node run"]
|
|
|
|
| 14 |
# CONTAINER FOR RUNNING BINARY
|
| 15 |
FROM alpine:3.18
|
| 16 |
COPY --from=build /src/dist/zkevm-node /app/zkevm-node
|
|
|
|
| 17 |
RUN apk update && apk add postgresql15-client
|
| 18 |
EXPOSE 8123
|
| 19 |
CMD ["/bin/sh", "-c", "/app/zkevm-node run"]
|
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM alpine:3.18
|
| 2 |
+
|
| 3 |
+
COPY zkevm-node /app/zkevm-node
|
| 4 |
+
|
| 5 |
+
EXPOSE 8123
|
| 6 |
+
|
| 7 |
+
RUN addgroup -S zkevm-group \
|
| 8 |
+
&& adduser -S zkevm-user -G zkevm-group
|
| 9 |
+
|
| 10 |
+
RUN chown -R zkevm-user:zkevm-group /app
|
| 11 |
+
|
| 12 |
+
USER zkevm-user
|
| 13 |
+
|
| 14 |
+
CMD ["/app/zkevm-node"]
|
| 15 |
+
|
|
@@ -3,6 +3,7 @@
|
|
| 3 |
import (
|
| 4 |
"bytes"
|
| 5 |
"context"
|
|
|
|
| 6 |
"encoding/json"
|
| 7 |
"errors"
|
| 8 |
"fmt"
|
|
@@ -106,6 +109,11 @@
|
|
| 106 |
// methodIDSequenceBatchesElderberry: MethodID for sequenceBatches in Elderberry
|
| 107 |
methodIDSequenceBatchesElderberry = []byte{0xde, 0xf5, 0x7e, 0x54} // 0xdef57e54 sequenceBatches((bytes,bytes32,uint64,bytes32)[],uint64,uint64,address)
|
| 108 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 109 |
// ErrNotFound is used when the object is not found
|
| 110 |
ErrNotFound = errors.New("not found")
|
| 111 |
// ErrIsReadOnlyMode is used when the EtherMan client is in read-only mode.
|
|
@@ -189,6 +197,7 @@
|
|
| 189 |
GlobalExitRootManager *polygonzkevmglobalexitroot.Polygonzkevmglobalexitroot
|
| 190 |
OldGlobalExitRootManager *oldpolygonzkevmglobalexitroot.Oldpolygonzkevmglobalexitroot
|
| 191 |
Pol *pol.Pol
|
|
|
|
| 192 |
SCAddresses []common.Address
|
| 193 |
|
| 194 |
RollupID uint32
|
|
@@ -198,10 +207,13 @@
|
|
| 198 |
l1Cfg L1Config
|
| 199 |
cfg Config
|
| 200 |
auth map[common.Address]bind.TransactOpts // empty in case of read-only client
|
|
|
|
|
|
|
|
|
|
| 201 |
}
|
| 202 |
|
| 203 |
// NewClient creates a new etherman.
|
| 204 |
-
func NewClient(cfg Config, l1Config L1Config) (*Client, error) {
|
| 205 |
// Connect to ethereum node
|
| 206 |
ethClient, err := ethclient.Dial(cfg.URL)
|
| 207 |
if err != nil {
|
|
@@ -244,6 +256,14 @@
|
|
| 244 |
log.Errorf("error creating NewPol client (%s). Error: %w", l1Config.PolAddr.String(), err)
|
| 245 |
return nil, err
|
| 246 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 247 |
var scAddresses []common.Address
|
| 248 |
scAddresses = append(scAddresses, l1Config.ZkEVMAddr, l1Config.RollupManagerAddr, l1Config.GlobalExitRootManagerAddr)
|
| 249 |
|
|
@@ -262,7 +282,7 @@
|
|
| 262 |
rollupID, err := rollupManager.RollupAddressToID(&bind.CallOpts{Pending: false}, l1Config.ZkEVMAddr)
|
| 263 |
if err != nil {
|
| 264 |
log.Debugf("error rollupManager.RollupAddressToID(%s). Error: %w", l1Config.RollupManagerAddr, err)
|
| 265 |
-
|
| 266 |
}
|
| 267 |
log.Debug("rollupID: ", rollupID)
|
| 268 |
|
|
@@ -274,6 +294,7 @@
|
|
| 274 |
RollupManager: rollupManager,
|
| 275 |
Pol: pol,
|
| 276 |
GlobalExitRootManager: globalExitRoot,
|
|
|
|
| 277 |
OldGlobalExitRootManager: oldGlobalExitRoot,
|
| 278 |
SCAddresses: scAddresses,
|
| 279 |
RollupID: rollupID,
|
|
@@ -284,11 +305,14 @@
|
|
| 284 |
l1Cfg: l1Config,
|
| 285 |
cfg: cfg,
|
| 286 |
auth: map[common.Address]bind.TransactOpts{},
|
|
|
|
|
|
|
| 287 |
}, nil
|
| 288 |
}
|
| 289 |
|
| 290 |
// VerifyGenBlockNumber verifies if the genesis Block Number is valid
|
| 291 |
func (etherMan *Client) VerifyGenBlockNumber(ctx context.Context, genBlockNumber uint64) (bool, error) {
|
|
|
|
| 292 |
start := time.Now()
|
| 293 |
log.Info("Verifying genesis blockNumber: ", genBlockNumber)
|
| 294 |
// Filter query
|
|
@@ -344,6 +368,11 @@
|
|
| 344 |
log.Debug("Getting forkIDs from blockNumber: ", genBlockNumber)
|
| 345 |
start := time.Now()
|
| 346 |
var logs []types.Log
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 347 |
log.Debug("Using ForkIDChunkSize: ", etherMan.cfg.ForkIDChunkSize)
|
| 348 |
for i := genBlockNumber; i <= lastL1BlockSynced; i = i + etherMan.cfg.ForkIDChunkSize + 1 {
|
| 349 |
final := i + etherMan.cfg.ForkIDChunkSize
|
|
@@ -684,61 +713,8 @@
|
|
| 684 |
return etherMan.updateForkId(ctx, vLog, blocks, blocksOrder, addExistingRollup.LastVerifiedBatchBeforeUpgrade, addExistingRollup.ForkID, "", addExistingRollup.RollupID)
|
| 685 |
}
|
| 686 |
|
| 687 |
-
func (etherMan *Client) updateEtrogSequence(
|
| 688 |
-
|
| 689 |
-
updateEtrogSequence, err := etherMan.EtrogZKEVM.ParseUpdateEtrogSequence(vLog)
|
| 690 |
-
if err != nil {
|
| 691 |
-
log.Error("error parsing updateEtrogSequence event. Error: ", err)
|
| 692 |
-
return err
|
| 693 |
-
}
|
| 694 |
-
|
| 695 |
-
// Read the tx for this event.
|
| 696 |
-
tx, err := etherMan.EthClient.TransactionInBlock(ctx, vLog.BlockHash, vLog.TxIndex)
|
| 697 |
-
if err != nil {
|
| 698 |
-
return err
|
| 699 |
-
}
|
| 700 |
-
if tx.Hash() != vLog.TxHash {
|
| 701 |
-
return fmt.Errorf("error: tx hash mismatch. want: %s have: %s", vLog.TxHash, tx.Hash().String())
|
| 702 |
-
}
|
| 703 |
-
msg, err := core.TransactionToMessage(tx, types.NewLondonSigner(tx.ChainId()), big.NewInt(0))
|
| 704 |
-
if err != nil {
|
| 705 |
-
return err
|
| 706 |
-
}
|
| 707 |
-
fullBlock, err := etherMan.EthClient.BlockByHash(ctx, vLog.BlockHash)
|
| 708 |
-
if err != nil {
|
| 709 |
-
return fmt.Errorf("error getting fullBlockInfo. BlockNumber: %d. Error: %w", vLog.BlockNumber, err)
|
| 710 |
-
}
|
| 711 |
-
|
| 712 |
-
log.Info("update Etrog transaction sequence...")
|
| 713 |
-
sequence := UpdateEtrogSequence{
|
| 714 |
-
BatchNumber: updateEtrogSequence.NumBatch,
|
| 715 |
-
SequencerAddr: updateEtrogSequence.Sequencer,
|
| 716 |
-
TxHash: vLog.TxHash,
|
| 717 |
-
Nonce: msg.Nonce,
|
| 718 |
-
PolygonRollupBaseEtrogBatchData: &polygonzkevm.PolygonRollupBaseEtrogBatchData{
|
| 719 |
-
Transactions: updateEtrogSequence.Transactions,
|
| 720 |
-
ForcedGlobalExitRoot: updateEtrogSequence.LastGlobalExitRoot,
|
| 721 |
-
ForcedTimestamp: fullBlock.Time(),
|
| 722 |
-
ForcedBlockHashL1: fullBlock.ParentHash(),
|
| 723 |
-
},
|
| 724 |
-
}
|
| 725 |
-
|
| 726 |
-
if len(*blocks) == 0 || ((*blocks)[len(*blocks)-1].BlockHash != vLog.BlockHash || (*blocks)[len(*blocks)-1].BlockNumber != vLog.BlockNumber) {
|
| 727 |
-
block := prepareBlock(vLog, time.Unix(int64(fullBlock.Time()), 0), fullBlock)
|
| 728 |
-
block.UpdateEtrogSequence = sequence
|
| 729 |
-
*blocks = append(*blocks, block)
|
| 730 |
-
} else if (*blocks)[len(*blocks)-1].BlockHash == vLog.BlockHash && (*blocks)[len(*blocks)-1].BlockNumber == vLog.BlockNumber {
|
| 731 |
-
(*blocks)[len(*blocks)-1].UpdateEtrogSequence = sequence
|
| 732 |
-
} else {
|
| 733 |
-
log.Error("Error processing UpdateEtrogSequence event. BlockHash:", vLog.BlockHash, ". BlockNumber: ", vLog.BlockNumber)
|
| 734 |
-
return fmt.Errorf("error processing UpdateEtrogSequence event")
|
| 735 |
-
}
|
| 736 |
-
or := Order{
|
| 737 |
-
Name: UpdateEtrogSequenceOrder,
|
| 738 |
-
Pos: 0,
|
| 739 |
-
}
|
| 740 |
-
(*blocksOrder)[(*blocks)[len(*blocks)-1].BlockHash] = append((*blocksOrder)[(*blocks)[len(*blocks)-1].BlockHash], or)
|
| 741 |
-
return nil
|
| 742 |
}
|
| 743 |
|
| 744 |
func (etherMan *Client) initialSequenceBatches(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
|
@@ -937,14 +913,14 @@
|
|
| 937 |
}
|
| 938 |
|
| 939 |
// EstimateGasSequenceBatches estimates gas for sending batches
|
| 940 |
-
func (etherMan *Client) EstimateGasSequenceBatches(sender common.Address, sequences []ethmanTypes.Sequence, maxSequenceTimestamp uint64, lastSequencedBatchNumber uint64, l2Coinbase common.Address) (*types.Transaction, error) {
|
| 941 |
opts, err := etherMan.getAuthByAddress(sender)
|
| 942 |
if err == ErrNotFound {
|
| 943 |
return nil, ErrPrivateKeyNotFound
|
| 944 |
}
|
| 945 |
opts.NoSend = true
|
| 946 |
|
| 947 |
-
tx, err := etherMan.sequenceBatches(opts, sequences, maxSequenceTimestamp, lastSequencedBatchNumber, l2Coinbase)
|
| 948 |
if err != nil {
|
| 949 |
return nil, err
|
| 950 |
}
|
|
@@ -953,7 +929,7 @@
|
|
| 953 |
}
|
| 954 |
|
| 955 |
// BuildSequenceBatchesTxData builds a []bytes to be sent to the PoE SC method SequenceBatches.
|
| 956 |
-
func (etherMan *Client) BuildSequenceBatchesTxData(sender common.Address, sequences []ethmanTypes.Sequence, maxSequenceTimestamp uint64, lastSequencedBatchNumber uint64, l2Coinbase common.Address) (to *common.Address, data []byte, err error) {
|
| 957 |
opts, err := etherMan.getAuthByAddress(sender)
|
| 958 |
if err == ErrNotFound {
|
| 959 |
return nil, nil, fmt.Errorf("failed to build sequence batches, err: %w", ErrPrivateKeyNotFound)
|
|
@@ -964,7 +940,7 @@
|
|
| 964 |
opts.GasLimit = uint64(1)
|
| 965 |
opts.GasPrice = big.NewInt(1)
|
| 966 |
|
| 967 |
-
tx, err := etherMan.sequenceBatches(opts, sequences, maxSequenceTimestamp, lastSequencedBatchNumber, l2Coinbase)
|
| 968 |
if err != nil {
|
| 969 |
return nil, nil, err
|
| 970 |
}
|
|
@@ -972,15 +948,15 @@
|
|
| 972 |
return tx.To(), tx.Data(), nil
|
| 973 |
}
|
| 974 |
|
| 975 |
-
func (etherMan *Client) sequenceBatches(opts bind.TransactOpts, sequences []ethmanTypes.Sequence, maxSequenceTimestamp uint64, lastSequencedBatchNumber uint64, l2Coinbase common.Address) (*types.Transaction, error) {
|
| 976 |
-
var batches []polygonzkevm.
|
| 977 |
for _, seq := range sequences {
|
| 978 |
var ger common.Hash
|
| 979 |
if seq.ForcedBatchTimestamp > 0 {
|
| 980 |
ger = seq.GlobalExitRoot
|
| 981 |
}
|
| 982 |
-
batch := polygonzkevm.
|
| 983 |
-
|
| 984 |
ForcedGlobalExitRoot: ger,
|
| 985 |
ForcedTimestamp: uint64(seq.ForcedBatchTimestamp),
|
| 986 |
ForcedBlockHashL1: seq.PrevBlockHash,
|
|
@@ -989,7 +965,7 @@
|
|
| 989 |
batches = append(batches, batch)
|
| 990 |
}
|
| 991 |
|
| 992 |
-
tx, err := etherMan.ZkEVM.
|
| 993 |
if err != nil {
|
| 994 |
log.Debugf("Batches to send: %+v", batches)
|
| 995 |
log.Debug("l2CoinBase: ", l2Coinbase)
|
|
@@ -1185,7 +1161,6 @@
|
|
| 1185 |
|
| 1186 |
func (etherMan *Client) sequencedBatchesEvent(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
| 1187 |
log.Debugf("SequenceBatches event detected: txHash: %s", common.Bytes2Hex(vLog.TxHash[:]))
|
| 1188 |
-
//tx,isPending, err:=etherMan.EthClient.TransactionByHash(ctx, vLog.TxHash)
|
| 1189 |
|
| 1190 |
sb, err := etherMan.ZkEVM.ParseSequenceBatches(vLog)
|
| 1191 |
if err != nil {
|
|
@@ -1209,13 +1184,15 @@
|
|
| 1209 |
if sb.NumBatch != 1 {
|
| 1210 |
methodId := tx.Data()[:4]
|
| 1211 |
log.Debugf("MethodId: %s", common.Bytes2Hex(methodId))
|
| 1212 |
-
if bytes.Equal(methodId, methodIDSequenceBatchesEtrog)
|
| 1213 |
-
|
|
|
|
| 1214 |
if err != nil {
|
| 1215 |
return fmt.Errorf("error decoding the sequences (etrog): %v", err)
|
| 1216 |
}
|
| 1217 |
-
} else if bytes.Equal(methodId, methodIDSequenceBatchesElderberry)
|
| 1218 |
-
|
|
|
|
| 1219 |
if err != nil {
|
| 1220 |
return fmt.Errorf("error decoding the sequences (elderberry): %v", err)
|
| 1221 |
}
|
|
@@ -1301,7 +1278,8 @@
|
|
| 1301 |
return nil
|
| 1302 |
}
|
| 1303 |
|
| 1304 |
-
func decodeSequencesElderberry(txData []byte, lastBatchNumber uint64, sequencer common.Address, txHash common.Hash, nonce uint64,
|
|
|
|
| 1305 |
// Extract coded txs.
|
| 1306 |
// Load contract ABI
|
| 1307 |
smcAbi, err := abi.JSON(strings.NewReader(polygonzkevm.PolygonzkevmABI))
|
|
@@ -1309,6 +1287,25 @@
|
|
| 1309 |
return nil, err
|
| 1310 |
}
|
| 1311 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1312 |
// Recover Method from signature and ABI
|
| 1313 |
method, err := smcAbi.MethodById(txData[:4])
|
| 1314 |
if err != nil {
|
|
@@ -1320,87 +1317,212 @@
|
|
| 1320 |
if err != nil {
|
| 1321 |
return nil, err
|
| 1322 |
}
|
| 1323 |
-
var sequences []polygonzkevm.PolygonRollupBaseEtrogBatchData
|
| 1324 |
bytedata, err := json.Marshal(data[0])
|
| 1325 |
if err != nil {
|
| 1326 |
return nil, err
|
| 1327 |
}
|
| 1328 |
-
err = json.Unmarshal(bytedata, &sequences)
|
| 1329 |
-
if err != nil {
|
| 1330 |
-
return nil, err
|
| 1331 |
-
}
|
| 1332 |
-
maxSequenceTimestamp := data[1].(uint64)
|
| 1333 |
-
initSequencedBatchNumber := data[2].(uint64)
|
| 1334 |
-
coinbase := (data[3]).(common.Address)
|
| 1335 |
-
sequencedBatches := make([]SequencedBatch, len(sequences))
|
| 1336 |
|
| 1337 |
-
|
| 1338 |
-
|
| 1339 |
-
|
| 1340 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1341 |
}
|
| 1342 |
-
|
| 1343 |
-
|
| 1344 |
-
|
| 1345 |
-
|
| 1346 |
-
|
| 1347 |
-
|
| 1348 |
-
|
| 1349 |
-
|
| 1350 |
-
|
| 1351 |
-
|
| 1352 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1353 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1354 |
}
|
| 1355 |
|
| 1356 |
-
return
|
| 1357 |
}
|
| 1358 |
|
| 1359 |
-
|
| 1360 |
-
|
| 1361 |
-
|
| 1362 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1363 |
if err != nil {
|
| 1364 |
return nil, err
|
| 1365 |
}
|
| 1366 |
-
|
| 1367 |
-
// Recover Method from signature and ABI
|
| 1368 |
-
method, err := smcAbi.MethodById(txData[:4])
|
| 1369 |
if err != nil {
|
| 1370 |
return nil, err
|
| 1371 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1372 |
|
| 1373 |
-
|
| 1374 |
-
|
| 1375 |
-
|
| 1376 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1377 |
}
|
| 1378 |
-
|
| 1379 |
-
|
|
|
|
|
|
|
| 1380 |
if err != nil {
|
| 1381 |
return nil, err
|
| 1382 |
}
|
| 1383 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1384 |
if err != nil {
|
| 1385 |
return nil, err
|
| 1386 |
}
|
| 1387 |
-
|
| 1388 |
-
|
| 1389 |
-
|
| 1390 |
-
|
| 1391 |
-
|
| 1392 |
-
|
| 1393 |
-
|
| 1394 |
-
|
| 1395 |
-
|
| 1396 |
-
|
| 1397 |
-
Nonce: nonce,
|
| 1398 |
-
Coinbase: coinbase,
|
| 1399 |
-
PolygonRollupBaseEtrogBatchData: &s,
|
| 1400 |
}
|
| 1401 |
}
|
| 1402 |
-
|
| 1403 |
-
return sequencedBatches, nil
|
| 1404 |
}
|
| 1405 |
|
| 1406 |
func decodeSequencesPreEtrog(txData []byte, lastBatchNumber uint64, sequencer common.Address, txHash common.Hash, nonce uint64) ([]SequencedBatch, error) {
|
|
@@ -1513,7 +1635,7 @@
|
|
| 1513 |
if err != nil {
|
| 1514 |
return err
|
| 1515 |
}
|
| 1516 |
-
// TODO
|
| 1517 |
|
| 1518 |
// Read the tx for this batch.
|
| 1519 |
tx, err := etherMan.EthClient.TransactionInBlock(ctx, vLog.BlockHash, vLog.TxIndex)
|
|
@@ -1818,6 +1940,17 @@
|
|
| 1818 |
})
|
| 1819 |
}
|
| 1820 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1821 |
// CheckTxWasMined check if a tx was already mined
|
| 1822 |
func (etherMan *Client) CheckTxWasMined(ctx context.Context, txHash common.Hash) (bool, *types.Receipt, error) {
|
| 1823 |
receipt, err := etherMan.EthClient.TransactionReceipt(ctx, txHash)
|
|
@@ -1872,15 +2005,15 @@
|
|
| 1872 |
}
|
| 1873 |
|
| 1874 |
// LoadAuthFromKeyStore loads an authorization from a key store file
|
| 1875 |
-
func (etherMan *Client) LoadAuthFromKeyStore(path, password string) (*bind.TransactOpts, error) {
|
| 1876 |
-
auth, err := newAuthFromKeystore(path, password, etherMan.l1Cfg.L1ChainID)
|
| 1877 |
if err != nil {
|
| 1878 |
-
return nil, err
|
| 1879 |
}
|
| 1880 |
|
| 1881 |
log.Infof("loaded authorization for address: %v", auth.From.String())
|
| 1882 |
etherMan.auth[auth.From] = auth
|
| 1883 |
-
return &auth, nil
|
| 1884 |
}
|
| 1885 |
|
| 1886 |
// newKeyFromKeystore creates an instance of a keystore key from a keystore file
|
|
@@ -1901,20 +2034,20 @@
|
|
| 1901 |
}
|
| 1902 |
|
| 1903 |
// newAuthFromKeystore an authorization instance from a keystore file
|
| 1904 |
-
func newAuthFromKeystore(path, password string, chainID uint64) (bind.TransactOpts, error) {
|
| 1905 |
log.Infof("reading key from: %v", path)
|
| 1906 |
key, err := newKeyFromKeystore(path, password)
|
| 1907 |
if err != nil {
|
| 1908 |
-
return bind.TransactOpts{}, err
|
| 1909 |
}
|
| 1910 |
if key == nil {
|
| 1911 |
-
return bind.TransactOpts{}, nil
|
| 1912 |
}
|
| 1913 |
auth, err := bind.NewKeyedTransactorWithChainID(key.PrivateKey, new(big.Int).SetUint64(chainID))
|
| 1914 |
if err != nil {
|
| 1915 |
-
return bind.TransactOpts{}, err
|
| 1916 |
}
|
| 1917 |
-
return *auth, nil
|
| 1918 |
}
|
| 1919 |
|
| 1920 |
// getAuthByAddress tries to get an authorization from the authorizations map
|
|
@@ -1942,3 +2075,28 @@
|
|
| 1942 |
|
| 1943 |
return *auth, nil
|
| 1944 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
import (
|
| 4 |
"bytes"
|
| 5 |
"context"
|
| 6 |
+
"crypto/ecdsa"
|
| 7 |
"encoding/json"
|
| 8 |
"errors"
|
| 9 |
"fmt"
|
|
|
|
| 109 |
// methodIDSequenceBatchesElderberry: MethodID for sequenceBatches in Elderberry
|
| 110 |
methodIDSequenceBatchesElderberry = []byte{0xde, 0xf5, 0x7e, 0x54} // 0xdef57e54 sequenceBatches((bytes,bytes32,uint64,bytes32)[],uint64,uint64,address)
|
| 111 |
|
| 112 |
+
// methodIDSequenceBatchesValidiumEtrog: MethodID for sequenceBatchesValidium in Etrog
|
| 113 |
+
methodIDSequenceBatchesValidiumEtrog = []byte{0x2d, 0x72, 0xc2, 0x48} // 0x2d72c248 sequenceBatchesValidium((bytes32,bytes32,uint64,bytes32)[],address,bytes)
|
| 114 |
+
// methodIDSequenceBatchesValidiumElderberry: MethodID for sequenceBatchesValidium in Elderberry
|
| 115 |
+
methodIDSequenceBatchesValidiumElderberry = []byte{0xdb, 0x5b, 0x0e, 0xd7} // 0xdb5b0ed7 sequenceBatchesValidium((bytes32,bytes32,uint64,bytes32)[],uint64,uint64,address,bytes)
|
| 116 |
+
|
| 117 |
// ErrNotFound is used when the object is not found
|
| 118 |
ErrNotFound = errors.New("not found")
|
| 119 |
// ErrIsReadOnlyMode is used when the EtherMan client is in read-only mode.
|
|
|
|
| 197 |
GlobalExitRootManager *polygonzkevmglobalexitroot.Polygonzkevmglobalexitroot
|
| 198 |
OldGlobalExitRootManager *oldpolygonzkevmglobalexitroot.Oldpolygonzkevmglobalexitroot
|
| 199 |
Pol *pol.Pol
|
| 200 |
+
DAProtocol *dataavailabilityprotocol.Dataavailabilityprotocol
|
| 201 |
SCAddresses []common.Address
|
| 202 |
|
| 203 |
RollupID uint32
|
|
|
|
| 207 |
l1Cfg L1Config
|
| 208 |
cfg Config
|
| 209 |
auth map[common.Address]bind.TransactOpts // empty in case of read-only client
|
| 210 |
+
|
| 211 |
+
da dataavailability.BatchDataProvider
|
| 212 |
+
state stateProvider
|
| 213 |
}
|
| 214 |
|
| 215 |
// NewClient creates a new etherman.
|
| 216 |
+
func NewClient(cfg Config, l1Config L1Config, da dataavailability.BatchDataProvider, st stateProvider) (*Client, error) {
|
| 217 |
// Connect to ethereum node
|
| 218 |
ethClient, err := ethclient.Dial(cfg.URL)
|
| 219 |
if err != nil {
|
|
|
|
| 256 |
log.Errorf("error creating NewPol client (%s). Error: %w", l1Config.PolAddr.String(), err)
|
| 257 |
return nil, err
|
| 258 |
}
|
| 259 |
+
dapAddr, err := zkevm.DataAvailabilityProtocol(&bind.CallOpts{Pending: false})
|
| 260 |
+
if err != nil {
|
| 261 |
+
return nil, err
|
| 262 |
+
}
|
| 263 |
+
dap, err := dataavailabilityprotocol.NewDataavailabilityprotocol(dapAddr, ethClient)
|
| 264 |
+
if err != nil {
|
| 265 |
+
return nil, err
|
| 266 |
+
}
|
| 267 |
var scAddresses []common.Address
|
| 268 |
scAddresses = append(scAddresses, l1Config.ZkEVMAddr, l1Config.RollupManagerAddr, l1Config.GlobalExitRootManagerAddr)
|
| 269 |
|
|
|
|
| 282 |
rollupID, err := rollupManager.RollupAddressToID(&bind.CallOpts{Pending: false}, l1Config.ZkEVMAddr)
|
| 283 |
if err != nil {
|
| 284 |
log.Debugf("error rollupManager.RollupAddressToID(%s). Error: %w", l1Config.RollupManagerAddr, err)
|
| 285 |
+
return nil, err
|
| 286 |
}
|
| 287 |
log.Debug("rollupID: ", rollupID)
|
| 288 |
|
|
|
|
| 294 |
RollupManager: rollupManager,
|
| 295 |
Pol: pol,
|
| 296 |
GlobalExitRootManager: globalExitRoot,
|
| 297 |
+
DAProtocol: dap,
|
| 298 |
OldGlobalExitRootManager: oldGlobalExitRoot,
|
| 299 |
SCAddresses: scAddresses,
|
| 300 |
RollupID: rollupID,
|
|
|
|
| 305 |
l1Cfg: l1Config,
|
| 306 |
cfg: cfg,
|
| 307 |
auth: map[common.Address]bind.TransactOpts{},
|
| 308 |
+
da: da,
|
| 309 |
+
state: st,
|
| 310 |
}, nil
|
| 311 |
}
|
| 312 |
|
| 313 |
// VerifyGenBlockNumber verifies if the genesis Block Number is valid
|
| 314 |
func (etherMan *Client) VerifyGenBlockNumber(ctx context.Context, genBlockNumber uint64) (bool, error) {
|
| 315 |
+
// TODO: do not assume that only one rollup will be attached to the rollup manager in the same L1 block
|
| 316 |
start := time.Now()
|
| 317 |
log.Info("Verifying genesis blockNumber: ", genBlockNumber)
|
| 318 |
// Filter query
|
|
|
|
| 368 |
log.Debug("Getting forkIDs from blockNumber: ", genBlockNumber)
|
| 369 |
start := time.Now()
|
| 370 |
var logs []types.Log
|
| 371 |
+
|
| 372 |
+
if lastL1BlockSynced < genBlockNumber {
|
| 373 |
+
lastL1BlockSynced = genBlockNumber
|
| 374 |
+
}
|
| 375 |
+
|
| 376 |
log.Debug("Using ForkIDChunkSize: ", etherMan.cfg.ForkIDChunkSize)
|
| 377 |
for i := genBlockNumber; i <= lastL1BlockSynced; i = i + etherMan.cfg.ForkIDChunkSize + 1 {
|
| 378 |
final := i + etherMan.cfg.ForkIDChunkSize
|
|
|
|
| 713 |
return etherMan.updateForkId(ctx, vLog, blocks, blocksOrder, addExistingRollup.LastVerifiedBatchBeforeUpgrade, addExistingRollup.ForkID, "", addExistingRollup.RollupID)
|
| 714 |
}
|
| 715 |
|
| 716 |
+
func (etherMan *Client) updateEtrogSequence(_ context.Context, _ types.Log, _ *[]Block, _ *map[common.Hash][]Order) error {
|
| 717 |
+
return errors.New("upgrading validiums to etrog not supported")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 718 |
}
|
| 719 |
|
| 720 |
func (etherMan *Client) initialSequenceBatches(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
|
|
|
| 913 |
}
|
| 914 |
|
| 915 |
// EstimateGasSequenceBatches estimates gas for sending batches
|
| 916 |
+
func (etherMan *Client) EstimateGasSequenceBatches(sender common.Address, sequences []ethmanTypes.Sequence, maxSequenceTimestamp uint64, lastSequencedBatchNumber uint64, l2Coinbase common.Address, dataAvailabilityMessage []byte) (*types.Transaction, error) {
|
| 917 |
opts, err := etherMan.getAuthByAddress(sender)
|
| 918 |
if err == ErrNotFound {
|
| 919 |
return nil, ErrPrivateKeyNotFound
|
| 920 |
}
|
| 921 |
opts.NoSend = true
|
| 922 |
|
| 923 |
+
tx, err := etherMan.sequenceBatches(opts, sequences, maxSequenceTimestamp, lastSequencedBatchNumber, l2Coinbase, dataAvailabilityMessage)
|
| 924 |
if err != nil {
|
| 925 |
return nil, err
|
| 926 |
}
|
|
|
|
| 929 |
}
|
| 930 |
|
| 931 |
// BuildSequenceBatchesTxData builds a []bytes to be sent to the PoE SC method SequenceBatches.
|
| 932 |
+
func (etherMan *Client) BuildSequenceBatchesTxData(sender common.Address, sequences []ethmanTypes.Sequence, maxSequenceTimestamp uint64, lastSequencedBatchNumber uint64, l2Coinbase common.Address, dataAvailabilityMessage []byte) (to *common.Address, data []byte, err error) {
|
| 933 |
opts, err := etherMan.getAuthByAddress(sender)
|
| 934 |
if err == ErrNotFound {
|
| 935 |
return nil, nil, fmt.Errorf("failed to build sequence batches, err: %w", ErrPrivateKeyNotFound)
|
|
|
|
| 940 |
opts.GasLimit = uint64(1)
|
| 941 |
opts.GasPrice = big.NewInt(1)
|
| 942 |
|
| 943 |
+
tx, err := etherMan.sequenceBatches(opts, sequences, maxSequenceTimestamp, lastSequencedBatchNumber, l2Coinbase, dataAvailabilityMessage)
|
| 944 |
if err != nil {
|
| 945 |
return nil, nil, err
|
| 946 |
}
|
|
|
|
| 948 |
return tx.To(), tx.Data(), nil
|
| 949 |
}
|
| 950 |
|
| 951 |
+
func (etherMan *Client) sequenceBatches(opts bind.TransactOpts, sequences []ethmanTypes.Sequence, maxSequenceTimestamp uint64, lastSequencedBatchNumber uint64, l2Coinbase common.Address, dataAvailabilityMessage []byte) (*types.Transaction, error) {
|
| 952 |
+
var batches []polygonzkevm.PolygonValidiumEtrogValidiumBatchData
|
| 953 |
for _, seq := range sequences {
|
| 954 |
var ger common.Hash
|
| 955 |
if seq.ForcedBatchTimestamp > 0 {
|
| 956 |
ger = seq.GlobalExitRoot
|
| 957 |
}
|
| 958 |
+
batch := polygonzkevm.PolygonValidiumEtrogValidiumBatchData{
|
| 959 |
+
TransactionsHash: crypto.Keccak256Hash(seq.BatchL2Data),
|
| 960 |
ForcedGlobalExitRoot: ger,
|
| 961 |
ForcedTimestamp: uint64(seq.ForcedBatchTimestamp),
|
| 962 |
ForcedBlockHashL1: seq.PrevBlockHash,
|
|
|
|
| 965 |
batches = append(batches, batch)
|
| 966 |
}
|
| 967 |
|
| 968 |
+
tx, err := etherMan.ZkEVM.SequenceBatchesValidium(&opts, batches, maxSequenceTimestamp, lastSequencedBatchNumber, l2Coinbase, dataAvailabilityMessage)
|
| 969 |
if err != nil {
|
| 970 |
log.Debugf("Batches to send: %+v", batches)
|
| 971 |
log.Debug("l2CoinBase: ", l2Coinbase)
|
|
|
|
| 1161 |
|
| 1162 |
func (etherMan *Client) sequencedBatchesEvent(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
|
| 1163 |
log.Debugf("SequenceBatches event detected: txHash: %s", common.Bytes2Hex(vLog.TxHash[:]))
|
|
|
|
| 1164 |
|
| 1165 |
sb, err := etherMan.ZkEVM.ParseSequenceBatches(vLog)
|
| 1166 |
if err != nil {
|
|
|
|
| 1184 |
if sb.NumBatch != 1 {
|
| 1185 |
methodId := tx.Data()[:4]
|
| 1186 |
log.Debugf("MethodId: %s", common.Bytes2Hex(methodId))
|
| 1187 |
+
if bytes.Equal(methodId, methodIDSequenceBatchesEtrog) ||
|
| 1188 |
+
bytes.Equal(methodId, methodIDSequenceBatchesValidiumEtrog) {
|
| 1189 |
+
sequences, err = decodeSequencesEtrog(tx.Data(), sb.NumBatch, msg.From, vLog.TxHash, msg.Nonce, sb.L1InfoRoot, etherMan.da, etherMan.state)
|
| 1190 |
if err != nil {
|
| 1191 |
return fmt.Errorf("error decoding the sequences (etrog): %v", err)
|
| 1192 |
}
|
| 1193 |
+
} else if bytes.Equal(methodId, methodIDSequenceBatchesElderberry) ||
|
| 1194 |
+
bytes.Equal(methodId, methodIDSequenceBatchesValidiumElderberry) {
|
| 1195 |
+
sequences, err = decodeSequencesElderberry(tx.Data(), sb.NumBatch, msg.From, vLog.TxHash, msg.Nonce, sb.L1InfoRoot, etherMan.da, etherMan.state)
|
| 1196 |
if err != nil {
|
| 1197 |
return fmt.Errorf("error decoding the sequences (elderberry): %v", err)
|
| 1198 |
}
|
|
|
|
| 1278 |
return nil
|
| 1279 |
}
|
| 1280 |
|
| 1281 |
+
func decodeSequencesElderberry(txData []byte, lastBatchNumber uint64, sequencer common.Address, txHash common.Hash, nonce uint64,
|
| 1282 |
+
l1InfoRoot common.Hash, da dataavailability.BatchDataProvider, st stateProvider) ([]SequencedBatch, error) {
|
| 1283 |
// Extract coded txs.
|
| 1284 |
// Load contract ABI
|
| 1285 |
smcAbi, err := abi.JSON(strings.NewReader(polygonzkevm.PolygonzkevmABI))
|
|
|
|
| 1287 |
return nil, err
|
| 1288 |
}
|
| 1289 |
|
| 1290 |
+
return decodeSequencedBatches(smcAbi, txData, state.FORKID_ELDERBERRY, lastBatchNumber, sequencer, txHash, nonce, l1InfoRoot, da, st)
|
| 1291 |
+
}
|
| 1292 |
+
|
| 1293 |
+
func decodeSequencesEtrog(txData []byte, lastBatchNumber uint64, sequencer common.Address, txHash common.Hash, nonce uint64, l1InfoRoot common.Hash,
|
| 1294 |
+
da dataavailability.BatchDataProvider, st stateProvider) ([]SequencedBatch, error) {
|
| 1295 |
+
// Extract coded txs.
|
| 1296 |
+
// Load contract ABI
|
| 1297 |
+
smcAbi, err := abi.JSON(strings.NewReader(etrogpolygonzkevm.EtrogpolygonzkevmABI))
|
| 1298 |
+
if err != nil {
|
| 1299 |
+
return nil, err
|
| 1300 |
+
}
|
| 1301 |
+
|
| 1302 |
+
return decodeSequencedBatches(smcAbi, txData, state.FORKID_ETROG, lastBatchNumber, sequencer, txHash, nonce, l1InfoRoot, da, st)
|
| 1303 |
+
}
|
| 1304 |
+
|
| 1305 |
+
// decodeSequencedBatches decodes provided data, based on the funcName, whether it is rollup or validium data and returns sequenced batches
|
| 1306 |
+
func decodeSequencedBatches(smcAbi abi.ABI, txData []byte, forkID uint64, lastBatchNumber uint64,
|
| 1307 |
+
sequencer common.Address, txHash common.Hash, nonce uint64, l1InfoRoot common.Hash,
|
| 1308 |
+
da dataavailability.BatchDataProvider, st stateProvider) ([]SequencedBatch, error) {
|
| 1309 |
// Recover Method from signature and ABI
|
| 1310 |
method, err := smcAbi.MethodById(txData[:4])
|
| 1311 |
if err != nil {
|
|
|
|
| 1317 |
if err != nil {
|
| 1318 |
return nil, err
|
| 1319 |
}
|
|
|
|
| 1320 |
bytedata, err := json.Marshal(data[0])
|
| 1321 |
if err != nil {
|
| 1322 |
return nil, err
|
| 1323 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1324 |
|
| 1325 |
+
var (
|
| 1326 |
+
maxSequenceTimestamp uint64
|
| 1327 |
+
initSequencedBatchNumber uint64
|
| 1328 |
+
coinbase common.Address
|
| 1329 |
+
)
|
| 1330 |
+
|
| 1331 |
+
switch method.Name {
|
| 1332 |
+
case "sequenceBatches":
|
| 1333 |
+
var sequences []polygonzkevm.PolygonRollupBaseEtrogBatchData
|
| 1334 |
+
err := json.Unmarshal(bytedata, &sequences)
|
| 1335 |
+
if err != nil {
|
| 1336 |
+
return nil, err
|
| 1337 |
}
|
| 1338 |
+
|
| 1339 |
+
switch forkID {
|
| 1340 |
+
case state.FORKID_ETROG:
|
| 1341 |
+
coinbase = data[1].(common.Address)
|
| 1342 |
+
|
| 1343 |
+
case state.FORKID_ELDERBERRY:
|
| 1344 |
+
maxSequenceTimestamp = data[1].(uint64)
|
| 1345 |
+
initSequencedBatchNumber = data[2].(uint64)
|
| 1346 |
+
coinbase = data[3].(common.Address)
|
| 1347 |
+
}
|
| 1348 |
+
|
| 1349 |
+
sequencedBatches := make([]SequencedBatch, len(sequences))
|
| 1350 |
+
for i, seq := range sequences {
|
| 1351 |
+
bn := lastBatchNumber - uint64(len(sequences)-(i+1))
|
| 1352 |
+
s := seq
|
| 1353 |
+
batch := SequencedBatch{
|
| 1354 |
+
BatchNumber: bn,
|
| 1355 |
+
L1InfoRoot: &l1InfoRoot,
|
| 1356 |
+
SequencerAddr: sequencer,
|
| 1357 |
+
TxHash: txHash,
|
| 1358 |
+
Nonce: nonce,
|
| 1359 |
+
Coinbase: coinbase,
|
| 1360 |
+
PolygonRollupBaseEtrogBatchData: &s,
|
| 1361 |
+
}
|
| 1362 |
+
if forkID >= state.FORKID_ELDERBERRY {
|
| 1363 |
+
batch.SequencedBatchElderberryData = &SequencedBatchElderberryData{
|
| 1364 |
+
MaxSequenceTimestamp: maxSequenceTimestamp,
|
| 1365 |
+
InitSequencedBatchNumber: initSequencedBatchNumber,
|
| 1366 |
+
}
|
| 1367 |
+
}
|
| 1368 |
+
sequencedBatches[i] = batch
|
| 1369 |
}
|
| 1370 |
+
|
| 1371 |
+
return sequencedBatches, nil
|
| 1372 |
+
case "sequenceBatchesValidium":
|
| 1373 |
+
var (
|
| 1374 |
+
sequencesValidium []polygonzkevm.PolygonValidiumEtrogValidiumBatchData
|
| 1375 |
+
dataAvailabilityMsg []byte
|
| 1376 |
+
)
|
| 1377 |
+
err := json.Unmarshal(bytedata, &sequencesValidium)
|
| 1378 |
+
if err != nil {
|
| 1379 |
+
return nil, err
|
| 1380 |
+
}
|
| 1381 |
+
|
| 1382 |
+
switch forkID {
|
| 1383 |
+
case state.FORKID_ETROG:
|
| 1384 |
+
coinbase = data[1].(common.Address)
|
| 1385 |
+
dataAvailabilityMsg = data[2].([]byte)
|
| 1386 |
+
|
| 1387 |
+
case state.FORKID_ELDERBERRY:
|
| 1388 |
+
maxSequenceTimestamp = data[1].(uint64)
|
| 1389 |
+
initSequencedBatchNumber = data[2].(uint64)
|
| 1390 |
+
coinbase = data[3].(common.Address)
|
| 1391 |
+
dataAvailabilityMsg = data[4].([]byte)
|
| 1392 |
+
}
|
| 1393 |
+
|
| 1394 |
+
// Pair the batch number, hash, and if it is forced. This will allow
|
| 1395 |
+
// retrieval from different sources, and keep them in original order.
|
| 1396 |
+
var batchInfos []batchInfo
|
| 1397 |
+
for i, d := range sequencesValidium {
|
| 1398 |
+
bn := lastBatchNumber - uint64(len(sequencesValidium)-(i+1))
|
| 1399 |
+
forced := d.ForcedTimestamp > 0
|
| 1400 |
+
h := d.TransactionsHash
|
| 1401 |
+
batchInfos = append(batchInfos, batchInfo{num: bn, hash: h, isForced: forced})
|
| 1402 |
+
}
|
| 1403 |
+
|
| 1404 |
+
batchData, err := retrieveBatchData(da, st, batchInfos, dataAvailabilityMsg)
|
| 1405 |
+
if err != nil {
|
| 1406 |
+
return nil, err
|
| 1407 |
+
}
|
| 1408 |
+
|
| 1409 |
+
sequencedBatches := make([]SequencedBatch, len(sequencesValidium))
|
| 1410 |
+
for i, info := range batchInfos {
|
| 1411 |
+
bn := info.num
|
| 1412 |
+
s := polygonzkevm.PolygonRollupBaseEtrogBatchData{
|
| 1413 |
+
Transactions: batchData[i],
|
| 1414 |
+
ForcedGlobalExitRoot: sequencesValidium[i].ForcedGlobalExitRoot,
|
| 1415 |
+
ForcedTimestamp: sequencesValidium[i].ForcedTimestamp,
|
| 1416 |
+
ForcedBlockHashL1: sequencesValidium[i].ForcedBlockHashL1,
|
| 1417 |
+
}
|
| 1418 |
+
batch := SequencedBatch{
|
| 1419 |
+
BatchNumber: bn,
|
| 1420 |
+
L1InfoRoot: &l1InfoRoot,
|
| 1421 |
+
SequencerAddr: sequencer,
|
| 1422 |
+
TxHash: txHash,
|
| 1423 |
+
Nonce: nonce,
|
| 1424 |
+
Coinbase: coinbase,
|
| 1425 |
+
PolygonRollupBaseEtrogBatchData: &s,
|
| 1426 |
+
}
|
| 1427 |
+
if forkID >= state.FORKID_ELDERBERRY {
|
| 1428 |
+
elderberry := &SequencedBatchElderberryData{
|
| 1429 |
+
MaxSequenceTimestamp: maxSequenceTimestamp,
|
| 1430 |
+
InitSequencedBatchNumber: initSequencedBatchNumber,
|
| 1431 |
+
}
|
| 1432 |
+
batch.SequencedBatchElderberryData = elderberry
|
| 1433 |
+
}
|
| 1434 |
+
sequencedBatches[i] = batch
|
| 1435 |
+
}
|
| 1436 |
+
|
| 1437 |
+
return sequencedBatches, nil
|
| 1438 |
}
|
| 1439 |
|
| 1440 |
+
return nil, fmt.Errorf("unexpected method called in sequence batches transaction: %s", method.RawName)
|
| 1441 |
}
|
| 1442 |
|
| 1443 |
+
type batchInfo struct {
|
| 1444 |
+
num uint64
|
| 1445 |
+
hash common.Hash
|
| 1446 |
+
isForced bool
|
| 1447 |
+
}
|
| 1448 |
+
|
| 1449 |
+
func retrieveBatchData(da dataavailability.BatchDataProvider, st stateProvider, batchInfos []batchInfo, daMessage []byte) ([][]byte, error) {
|
| 1450 |
+
validiumData, err := getBatchL2Data(da, batchInfos, daMessage)
|
| 1451 |
if err != nil {
|
| 1452 |
return nil, err
|
| 1453 |
}
|
| 1454 |
+
forcedData, err := getForcedBatchData(st, batchInfos)
|
|
|
|
|
|
|
| 1455 |
if err != nil {
|
| 1456 |
return nil, err
|
| 1457 |
}
|
| 1458 |
+
data := make([][]byte, len(batchInfos))
|
| 1459 |
+
for i, info := range batchInfos {
|
| 1460 |
+
bn := info.num
|
| 1461 |
+
if info.isForced {
|
| 1462 |
+
data[i] = forcedData[bn]
|
| 1463 |
+
} else {
|
| 1464 |
+
data[i] = validiumData[bn]
|
| 1465 |
+
}
|
| 1466 |
+
}
|
| 1467 |
+
return data, nil
|
| 1468 |
+
}
|
| 1469 |
|
| 1470 |
+
func getBatchL2Data(da dataavailability.BatchDataProvider, batchInfos []batchInfo, daMessage []byte) (map[uint64][]byte, error) {
|
| 1471 |
+
var batchNums []uint64
|
| 1472 |
+
var batchHashes []common.Hash
|
| 1473 |
+
for _, info := range batchInfos {
|
| 1474 |
+
if !info.isForced {
|
| 1475 |
+
batchNums = append(batchNums, info.num)
|
| 1476 |
+
batchHashes = append(batchHashes, info.hash)
|
| 1477 |
+
}
|
| 1478 |
}
|
| 1479 |
+
if len(batchNums) == 0 {
|
| 1480 |
+
return nil, nil
|
| 1481 |
+
}
|
| 1482 |
+
batchL2Data, err := da.GetBatchL2Data(batchNums, batchHashes, daMessage)
|
| 1483 |
if err != nil {
|
| 1484 |
return nil, err
|
| 1485 |
}
|
| 1486 |
+
if len(batchL2Data) != len(batchNums) {
|
| 1487 |
+
return nil,
|
| 1488 |
+
fmt.Errorf("failed to retrieve all batch data. Expected %d, got %d", len(batchNums), len(batchL2Data))
|
| 1489 |
+
}
|
| 1490 |
+
data := make(map[uint64][]byte)
|
| 1491 |
+
for i, bn := range batchNums {
|
| 1492 |
+
data[bn] = batchL2Data[i]
|
| 1493 |
+
}
|
| 1494 |
+
return data, nil
|
| 1495 |
+
}
|
| 1496 |
+
|
| 1497 |
+
func getForcedBatchData(st stateProvider, batchInfos []batchInfo) (map[uint64][]byte, error) {
|
| 1498 |
+
var batchNums []uint64
|
| 1499 |
+
var batchHashes []common.Hash
|
| 1500 |
+
for _, info := range batchInfos {
|
| 1501 |
+
if info.isForced {
|
| 1502 |
+
batchNums = append(batchNums, info.num)
|
| 1503 |
+
batchHashes = append(batchHashes, info.hash)
|
| 1504 |
+
}
|
| 1505 |
+
}
|
| 1506 |
+
if len(batchNums) == 0 {
|
| 1507 |
+
return nil, nil
|
| 1508 |
+
}
|
| 1509 |
+
data, err := st.GetForcedBatchDataByNumbers(context.Background(), batchNums, nil)
|
| 1510 |
if err != nil {
|
| 1511 |
return nil, err
|
| 1512 |
}
|
| 1513 |
+
|
| 1514 |
+
for i, bn := range batchNums {
|
| 1515 |
+
expectedHash := batchHashes[i]
|
| 1516 |
+
d, ok := data[bn]
|
| 1517 |
+
if !ok {
|
| 1518 |
+
return nil, fmt.Errorf("missing forced batch data for number %d", bn)
|
| 1519 |
+
}
|
| 1520 |
+
actualHash := crypto.Keccak256Hash(d)
|
| 1521 |
+
if actualHash != expectedHash {
|
| 1522 |
+
return nil, fmt.Errorf("got wrong hash for forced batch data number %d", bn)
|
|
|
|
|
|
|
|
|
|
| 1523 |
}
|
| 1524 |
}
|
| 1525 |
+
return data, nil
|
|
|
|
| 1526 |
}
|
| 1527 |
|
| 1528 |
func decodeSequencesPreEtrog(txData []byte, lastBatchNumber uint64, sequencer common.Address, txHash common.Hash, nonce uint64) ([]SequencedBatch, error) {
|
|
|
|
| 1635 |
if err != nil {
|
| 1636 |
return err
|
| 1637 |
}
|
| 1638 |
+
// TODO complete data forcedBlockHash, forcedGer y forcedTimestamp
|
| 1639 |
|
| 1640 |
// Read the tx for this batch.
|
| 1641 |
tx, err := etherMan.EthClient.TransactionInBlock(ctx, vLog.BlockHash, vLog.TxIndex)
|
|
|
|
| 1940 |
})
|
| 1941 |
}
|
| 1942 |
|
| 1943 |
+
// DepositCount returns deposits count
|
| 1944 |
+
func (etherman *Client) DepositCount(ctx context.Context, blockNumber *uint64) (*big.Int, error) {
|
| 1945 |
+
var opts *bind.CallOpts
|
| 1946 |
+
if blockNumber != nil {
|
| 1947 |
+
opts = new(bind.CallOpts)
|
| 1948 |
+
opts.BlockNumber = new(big.Int).SetUint64(*blockNumber)
|
| 1949 |
+
}
|
| 1950 |
+
|
| 1951 |
+
return etherman.GlobalExitRootManager.DepositCount(opts)
|
| 1952 |
+
}
|
| 1953 |
+
|
| 1954 |
// CheckTxWasMined check if a tx was already mined
|
| 1955 |
func (etherMan *Client) CheckTxWasMined(ctx context.Context, txHash common.Hash) (bool, *types.Receipt, error) {
|
| 1956 |
receipt, err := etherMan.EthClient.TransactionReceipt(ctx, txHash)
|
|
|
|
| 2005 |
}
|
| 2006 |
|
| 2007 |
// LoadAuthFromKeyStore loads an authorization from a key store file
|
| 2008 |
+
func (etherMan *Client) LoadAuthFromKeyStore(path, password string) (*bind.TransactOpts, *ecdsa.PrivateKey, error) {
|
| 2009 |
+
auth, pk, err := newAuthFromKeystore(path, password, etherMan.l1Cfg.L1ChainID)
|
| 2010 |
if err != nil {
|
| 2011 |
+
return nil, nil, err
|
| 2012 |
}
|
| 2013 |
|
| 2014 |
log.Infof("loaded authorization for address: %v", auth.From.String())
|
| 2015 |
etherMan.auth[auth.From] = auth
|
| 2016 |
+
return &auth, pk, nil
|
| 2017 |
}
|
| 2018 |
|
| 2019 |
// newKeyFromKeystore creates an instance of a keystore key from a keystore file
|
|
|
|
| 2034 |
}
|
| 2035 |
|
| 2036 |
// newAuthFromKeystore an authorization instance from a keystore file
|
| 2037 |
+
func newAuthFromKeystore(path, password string, chainID uint64) (bind.TransactOpts, *ecdsa.PrivateKey, error) {
|
| 2038 |
log.Infof("reading key from: %v", path)
|
| 2039 |
key, err := newKeyFromKeystore(path, password)
|
| 2040 |
if err != nil {
|
| 2041 |
+
return bind.TransactOpts{}, nil, err
|
| 2042 |
}
|
| 2043 |
if key == nil {
|
| 2044 |
+
return bind.TransactOpts{}, nil, nil
|
| 2045 |
}
|
| 2046 |
auth, err := bind.NewKeyedTransactorWithChainID(key.PrivateKey, new(big.Int).SetUint64(chainID))
|
| 2047 |
if err != nil {
|
| 2048 |
+
return bind.TransactOpts{}, nil, err
|
| 2049 |
}
|
| 2050 |
+
return *auth, key.PrivateKey, nil
|
| 2051 |
}
|
| 2052 |
|
| 2053 |
// getAuthByAddress tries to get an authorization from the authorizations map
|
|
|
|
| 2075 |
|
| 2076 |
return *auth, nil
|
| 2077 |
}
|
| 2078 |
+
|
| 2079 |
+
// GetDAProtocolAddr returns the address of the data availability protocol
|
| 2080 |
+
func (etherMan *Client) GetDAProtocolAddr() (common.Address, error) {
|
| 2081 |
+
return etherMan.ZkEVM.DataAvailabilityProtocol(&bind.CallOpts{Pending: false})
|
| 2082 |
+
}
|
| 2083 |
+
|
| 2084 |
+
// GetDAProtocolName returns the name of the data availability protocol
|
| 2085 |
+
func (etherMan *Client) GetDAProtocolName() (string, error) {
|
| 2086 |
+
return etherMan.DAProtocol.GetProcotolName(&bind.CallOpts{Pending: false})
|
| 2087 |
+
}
|
| 2088 |
+
|
| 2089 |
+
// SetDataAvailabilityProtocol sets the address for the new data availability protocol
|
| 2090 |
+
func (etherMan *Client) SetDataAvailabilityProtocol(from, daAddress common.Address) (*types.Transaction, error) {
|
| 2091 |
+
auth, err := etherMan.getAuthByAddress(from)
|
| 2092 |
+
if err != nil {
|
| 2093 |
+
return nil, err
|
| 2094 |
+
}
|
| 2095 |
+
|
| 2096 |
+
return etherMan.ZkEVM.SetDataAvailabilityProtocol(&auth, daAddress)
|
| 2097 |
+
}
|
| 2098 |
+
|
| 2099 |
+
// GetRollupId returns the rollup id
|
| 2100 |
+
func (etherMan *Client) GetRollupId() uint32 {
|
| 2101 |
+
return etherMan.RollupID
|
| 2102 |
+
}
|
|
@@ -38,7 +38,7 @@
|
|
| 38 |
}
|
| 39 |
|
| 40 |
// This function prepare the blockchain, the wallet with funds and deploy the smc
|
| 41 |
-
func newTestingEnv() (ethman *Client, ethBackend *simulated.Backend, auth *bind.TransactOpts, polAddr common.Address, br *polygonzkevmbridge.Polygonzkevmbridge) {
|
| 42 |
privateKey, err := crypto.GenerateKey()
|
| 43 |
if err != nil {
|
| 44 |
log.Fatal(err)
|
|
@@ -47,7 +47,9 @@
|
|
| 47 |
if err != nil {
|
| 48 |
log.Fatal(err)
|
| 49 |
}
|
| 50 |
-
|
|
|
|
|
|
|
| 51 |
if err != nil {
|
| 52 |
log.Fatal(err)
|
| 53 |
}
|
|
@@ -55,12 +57,12 @@
|
|
| 55 |
if err != nil {
|
| 56 |
log.Fatal(err)
|
| 57 |
}
|
| 58 |
-
return ethman, ethBackend, auth, polAddr, br
|
| 59 |
}
|
| 60 |
|
| 61 |
func TestGEREvent(t *testing.T) {
|
| 62 |
// Set up testing environment
|
| 63 |
-
etherman, ethBackend, auth, _, br := newTestingEnv()
|
| 64 |
|
| 65 |
// Read currentBlock
|
| 66 |
ctx := context.Background()
|
|
@@ -82,14 +84,14 @@
|
|
| 82 |
blocks, _, err := etherman.GetRollupInfoByBlockRange(ctx, initBlock.NumberU64(), &finalBlockNumber)
|
| 83 |
require.NoError(t, err)
|
| 84 |
t.Logf("Blocks: %+v", blocks)
|
| 85 |
-
assert.Equal(t, uint64(
|
| 86 |
assert.NotEqual(t, common.Hash{}, blocks[0].L1InfoTree[0].MainnetExitRoot)
|
| 87 |
assert.Equal(t, common.Hash{}, blocks[0].L1InfoTree[0].RollupExitRoot)
|
| 88 |
}
|
| 89 |
|
| 90 |
func TestForcedBatchEvent(t *testing.T) {
|
| 91 |
// Set up testing environment
|
| 92 |
-
etherman, ethBackend, auth, _, _ := newTestingEnv()
|
| 93 |
|
| 94 |
// Read currentBlock
|
| 95 |
ctx := context.Background()
|
|
@@ -114,8 +116,8 @@
|
|
| 114 |
blocks, _, err := etherman.GetRollupInfoByBlockRange(ctx, initBlock.NumberU64(), &finalBlockNumber)
|
| 115 |
require.NoError(t, err)
|
| 116 |
t.Logf("Blocks: %+v", blocks)
|
| 117 |
-
assert.Equal(t, uint64(
|
| 118 |
-
assert.Equal(t, uint64(
|
| 119 |
assert.NotEqual(t, common.Hash{}, blocks[0].ForcedBatches[0].GlobalExitRoot)
|
| 120 |
assert.NotEqual(t, time.Time{}, blocks[0].ForcedBatches[0].ForcedAt)
|
| 121 |
assert.Equal(t, uint64(1), blocks[0].ForcedBatches[0].ForcedBatchNumber)
|
|
@@ -125,7 +127,7 @@
|
|
| 125 |
|
| 126 |
func TestSequencedBatchesEvent(t *testing.T) {
|
| 127 |
// Set up testing environment
|
| 128 |
-
etherman, ethBackend, auth, _, br := newTestingEnv()
|
| 129 |
|
| 130 |
// Read currentBlock
|
| 131 |
ctx := context.Background()
|
|
@@ -156,13 +158,19 @@
|
|
| 156 |
blocks, _, err := etherman.GetRollupInfoByBlockRange(ctx, initBlock.NumberU64(), ¤tBlockNumber)
|
| 157 |
require.NoError(t, err)
|
| 158 |
t.Log("Blocks: ", blocks)
|
| 159 |
-
var sequences []polygonzkevm.
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
|
|
|
|
| 164 |
})
|
| 165 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 166 |
require.NoError(t, err)
|
| 167 |
|
| 168 |
// Mine the tx in a block
|
|
@@ -188,7 +196,7 @@
|
|
| 188 |
|
| 189 |
func TestVerifyBatchEvent(t *testing.T) {
|
| 190 |
// Set up testing environment
|
| 191 |
-
etherman, ethBackend, auth, _, _ := newTestingEnv()
|
| 192 |
|
| 193 |
// Read currentBlock
|
| 194 |
ctx := context.Background()
|
|
@@ -197,12 +205,13 @@
|
|
| 197 |
require.NoError(t, err)
|
| 198 |
|
| 199 |
rawTxs := "f84901843b9aca00827b0c945fbdb2315678afecb367f032d93f642f64180aa380a46057361d00000000000000000000000000000000000000000000000000000000000000048203e9808073efe1fa2d3e27f26f32208550ea9b0274d49050b816cadab05a771f4275d0242fd5d92b3fb89575c070e6c930587c520ee65a3aa8cfe382fcad20421bf51d621c"
|
| 200 |
-
tx := polygonzkevm.
|
| 201 |
-
|
| 202 |
}
|
| 203 |
-
|
| 204 |
-
_, err = etherman.ZkEVM.
|
| 205 |
require.NoError(t, err)
|
|
|
|
| 206 |
|
| 207 |
// Mine the tx in a block
|
| 208 |
ethBackend.Commit()
|
|
@@ -220,7 +229,7 @@
|
|
| 220 |
blocks, order, err := etherman.GetRollupInfoByBlockRange(ctx, initBlock.NumberU64(), &finalBlockNumber)
|
| 221 |
require.NoError(t, err)
|
| 222 |
t.Logf("Blocks: %+v, \nOrder: %+v", blocks, order)
|
| 223 |
-
assert.Equal(t, uint64(
|
| 224 |
assert.Equal(t, uint64(1), blocks[1].VerifiedBatches[0].BatchNumber)
|
| 225 |
assert.NotEqual(t, common.Address{}, blocks[1].VerifiedBatches[0].Aggregator)
|
| 226 |
assert.NotEqual(t, common.Hash{}, blocks[1].VerifiedBatches[0].TxHash)
|
|
@@ -232,7 +241,7 @@
|
|
| 232 |
|
| 233 |
func TestSequenceForceBatchesEvent(t *testing.T) {
|
| 234 |
// Set up testing environment
|
| 235 |
-
etherman, ethBackend, auth, _, _ := newTestingEnv()
|
| 236 |
|
| 237 |
// Read currentBlock
|
| 238 |
ctx := context.Background()
|
|
@@ -283,7 +292,7 @@
|
|
| 283 |
blocks, order, err := etherman.GetRollupInfoByBlockRange(ctx, initBlock.NumberU64(), &finalBlockNumber)
|
| 284 |
require.NoError(t, err)
|
| 285 |
t.Logf("Blocks: %+v", blocks)
|
| 286 |
-
assert.Equal(t, uint64(
|
| 287 |
assert.Equal(t, uint64(2), blocks[1].SequencedForceBatches[0][0].BatchNumber)
|
| 288 |
assert.Equal(t, forcedGer, common.BytesToHash(blocks[1].SequencedForceBatches[0][0].ForcedGlobalExitRoot[:]))
|
| 289 |
assert.Equal(t, forcedTimestamp, blocks[1].SequencedForceBatches[0][0].ForcedTimestamp)
|
|
@@ -293,7 +302,7 @@
|
|
| 293 |
|
| 294 |
func TestSendSequences(t *testing.T) {
|
| 295 |
// Set up testing environment
|
| 296 |
-
etherman, ethBackend, auth, _, br := newTestingEnv()
|
| 297 |
|
| 298 |
// Read currentBlock
|
| 299 |
ctx := context.Background()
|
|
@@ -315,10 +324,12 @@
|
|
| 315 |
BatchL2Data: batchL2Data,
|
| 316 |
LastL2BLockTimestamp: time.Now().Unix(),
|
| 317 |
}
|
|
|
|
| 318 |
lastL2BlockTStamp := tx1.Time().Unix()
|
| 319 |
-
|
| 320 |
-
tx, err := etherman.sequenceBatches(*auth, []ethmanTypes.Sequence{sequence}, uint64(lastL2BlockTStamp), uint64(1), auth.From)
|
| 321 |
require.NoError(t, err)
|
|
|
|
|
|
|
| 322 |
log.Debug("TX: ", tx.Hash())
|
| 323 |
ethBackend.Commit()
|
| 324 |
|
|
@@ -341,7 +352,7 @@
|
|
| 341 |
|
| 342 |
func TestGasPrice(t *testing.T) {
|
| 343 |
// Set up testing environment
|
| 344 |
-
etherman, _, _, _, _ := newTestingEnv()
|
| 345 |
etherscanM := new(etherscanMock)
|
| 346 |
ethGasStationM := new(ethGasStationMock)
|
| 347 |
etherman.GasProviders.Providers = []ethereum.GasPricer{etherman.EthClient, etherscanM, ethGasStationM}
|
|
@@ -360,14 +371,14 @@
|
|
| 360 |
|
| 361 |
func TestErrorEthGasStationPrice(t *testing.T) {
|
| 362 |
// Set up testing environment
|
| 363 |
-
etherman, _, _, _, _ := newTestingEnv()
|
| 364 |
ethGasStationM := new(ethGasStationMock)
|
| 365 |
etherman.GasProviders.Providers = []ethereum.GasPricer{etherman.EthClient, ethGasStationM}
|
| 366 |
ctx := context.Background()
|
| 367 |
|
| 368 |
ethGasStationM.On("SuggestGasPrice", ctx).Return(big.NewInt(0), fmt.Errorf("error getting gasPrice from ethGasStation"))
|
| 369 |
gp := etherman.GetL1GasPrice(ctx)
|
| 370 |
-
assert.Equal(t, big.NewInt(
|
| 371 |
|
| 372 |
etherscanM := new(etherscanMock)
|
| 373 |
etherman.GasProviders.Providers = []ethereum.GasPricer{etherman.EthClient, etherscanM, ethGasStationM}
|
|
@@ -379,7 +390,7 @@
|
|
| 379 |
|
| 380 |
func TestErrorEtherScanPrice(t *testing.T) {
|
| 381 |
// Set up testing environment
|
| 382 |
-
etherman, _, _, _, _ := newTestingEnv()
|
| 383 |
etherscanM := new(etherscanMock)
|
| 384 |
ethGasStationM := new(ethGasStationMock)
|
| 385 |
etherman.GasProviders.Providers = []ethereum.GasPricer{etherman.EthClient, etherscanM, ethGasStationM}
|
|
@@ -393,7 +404,7 @@
|
|
| 393 |
|
| 394 |
func TestGetForks(t *testing.T) {
|
| 395 |
// Set up testing environment
|
| 396 |
-
etherman, _, _, _, _ := newTestingEnv()
|
| 397 |
ctx := context.Background()
|
| 398 |
forks, err := etherman.GetForks(ctx, 0, 132)
|
| 399 |
require.NoError(t, err)
|
|
|
|
| 38 |
}
|
| 39 |
|
| 40 |
// This function prepare the blockchain, the wallet with funds and deploy the smc
|
| 41 |
+
func newTestingEnv(t *testing.T) (ethman *Client, ethBackend *simulated.Backend, auth *bind.TransactOpts, polAddr common.Address, br *polygonzkevmbridge.Polygonzkevmbridge, da *daMock, st *stateMock) {
|
| 42 |
privateKey, err := crypto.GenerateKey()
|
| 43 |
if err != nil {
|
| 44 |
log.Fatal(err)
|
|
|
|
| 47 |
if err != nil {
|
| 48 |
log.Fatal(err)
|
| 49 |
}
|
| 50 |
+
da = newDaMock(t)
|
| 51 |
+
st = newStateMock(t)
|
| 52 |
+
ethman, ethBackend, polAddr, br, err = NewSimulatedEtherman(Config{ForkIDChunkSize: 10}, auth, da, st)
|
| 53 |
if err != nil {
|
| 54 |
log.Fatal(err)
|
| 55 |
}
|
|
|
|
| 57 |
if err != nil {
|
| 58 |
log.Fatal(err)
|
| 59 |
}
|
| 60 |
+
return ethman, ethBackend, auth, polAddr, br, da, st
|
| 61 |
}
|
| 62 |
|
| 63 |
func TestGEREvent(t *testing.T) {
|
| 64 |
// Set up testing environment
|
| 65 |
+
etherman, ethBackend, auth, _, br, _, _ := newTestingEnv(t)
|
| 66 |
|
| 67 |
// Read currentBlock
|
| 68 |
ctx := context.Background()
|
|
|
|
| 84 |
blocks, _, err := etherman.GetRollupInfoByBlockRange(ctx, initBlock.NumberU64(), &finalBlockNumber)
|
| 85 |
require.NoError(t, err)
|
| 86 |
t.Logf("Blocks: %+v", blocks)
|
| 87 |
+
assert.Equal(t, uint64(11), blocks[0].L1InfoTree[0].BlockNumber)
|
| 88 |
assert.NotEqual(t, common.Hash{}, blocks[0].L1InfoTree[0].MainnetExitRoot)
|
| 89 |
assert.Equal(t, common.Hash{}, blocks[0].L1InfoTree[0].RollupExitRoot)
|
| 90 |
}
|
| 91 |
|
| 92 |
func TestForcedBatchEvent(t *testing.T) {
|
| 93 |
// Set up testing environment
|
| 94 |
+
etherman, ethBackend, auth, _, _, _, _ := newTestingEnv(t)
|
| 95 |
|
| 96 |
// Read currentBlock
|
| 97 |
ctx := context.Background()
|
|
|
|
| 116 |
blocks, _, err := etherman.GetRollupInfoByBlockRange(ctx, initBlock.NumberU64(), &finalBlockNumber)
|
| 117 |
require.NoError(t, err)
|
| 118 |
t.Logf("Blocks: %+v", blocks)
|
| 119 |
+
assert.Equal(t, uint64(11), blocks[0].BlockNumber)
|
| 120 |
+
assert.Equal(t, uint64(11), blocks[0].ForcedBatches[0].BlockNumber)
|
| 121 |
assert.NotEqual(t, common.Hash{}, blocks[0].ForcedBatches[0].GlobalExitRoot)
|
| 122 |
assert.NotEqual(t, time.Time{}, blocks[0].ForcedBatches[0].ForcedAt)
|
| 123 |
assert.Equal(t, uint64(1), blocks[0].ForcedBatches[0].ForcedBatchNumber)
|
|
|
|
| 127 |
|
| 128 |
func TestSequencedBatchesEvent(t *testing.T) {
|
| 129 |
// Set up testing environment
|
| 130 |
+
etherman, ethBackend, auth, _, br, da, _ := newTestingEnv(t)
|
| 131 |
|
| 132 |
// Read currentBlock
|
| 133 |
ctx := context.Background()
|
|
|
|
| 158 |
blocks, _, err := etherman.GetRollupInfoByBlockRange(ctx, initBlock.NumberU64(), ¤tBlockNumber)
|
| 159 |
require.NoError(t, err)
|
| 160 |
t.Log("Blocks: ", blocks)
|
| 161 |
+
var sequences []polygonzkevm.PolygonValidiumEtrogValidiumBatchData
|
| 162 |
+
txsHash := crypto.Keccak256Hash(common.Hex2Bytes(rawTxs))
|
| 163 |
+
sequences = append(sequences, polygonzkevm.PolygonValidiumEtrogValidiumBatchData{
|
| 164 |
+
TransactionsHash: txsHash,
|
| 165 |
+
}, polygonzkevm.PolygonValidiumEtrogValidiumBatchData{
|
| 166 |
+
TransactionsHash: txsHash,
|
| 167 |
})
|
| 168 |
+
batchNums := []uint64{2, 3}
|
| 169 |
+
batchHashes := []common.Hash{txsHash, txsHash}
|
| 170 |
+
batchData := [][]byte{data, data}
|
| 171 |
+
daMessage, _ := hex.DecodeString("0x123456789123456789")
|
| 172 |
+
da.Mock.On("GetBatchL2Data", batchNums, batchHashes, daMessage).Return(batchData, nil)
|
| 173 |
+
_, err = etherman.ZkEVM.SequenceBatchesValidium(auth, sequences, uint64(time.Now().Unix()), uint64(1), auth.From, daMessage)
|
| 174 |
require.NoError(t, err)
|
| 175 |
|
| 176 |
// Mine the tx in a block
|
|
|
|
| 196 |
|
| 197 |
func TestVerifyBatchEvent(t *testing.T) {
|
| 198 |
// Set up testing environment
|
| 199 |
+
etherman, ethBackend, auth, _, _, da, _ := newTestingEnv(t)
|
| 200 |
|
| 201 |
// Read currentBlock
|
| 202 |
ctx := context.Background()
|
|
|
|
| 205 |
require.NoError(t, err)
|
| 206 |
|
| 207 |
rawTxs := "f84901843b9aca00827b0c945fbdb2315678afecb367f032d93f642f64180aa380a46057361d00000000000000000000000000000000000000000000000000000000000000048203e9808073efe1fa2d3e27f26f32208550ea9b0274d49050b816cadab05a771f4275d0242fd5d92b3fb89575c070e6c930587c520ee65a3aa8cfe382fcad20421bf51d621c"
|
| 208 |
+
tx := polygonzkevm.PolygonValidiumEtrogValidiumBatchData{
|
| 209 |
+
TransactionsHash: crypto.Keccak256Hash(common.Hex2Bytes(rawTxs)),
|
| 210 |
}
|
| 211 |
+
daMessage, _ := hex.DecodeString("0x1234")
|
| 212 |
+
_, err = etherman.ZkEVM.SequenceBatchesValidium(auth, []polygonzkevm.PolygonValidiumEtrogValidiumBatchData{tx}, uint64(time.Now().Unix()), uint64(1), auth.From, daMessage)
|
| 213 |
require.NoError(t, err)
|
| 214 |
+
da.Mock.On("GetBatchL2Data", []uint64{2}, []common.Hash{crypto.Keccak256Hash(common.Hex2Bytes(rawTxs))}, daMessage).Return([][]byte{common.Hex2Bytes(rawTxs)}, nil)
|
| 215 |
|
| 216 |
// Mine the tx in a block
|
| 217 |
ethBackend.Commit()
|
|
|
|
| 229 |
blocks, order, err := etherman.GetRollupInfoByBlockRange(ctx, initBlock.NumberU64(), &finalBlockNumber)
|
| 230 |
require.NoError(t, err)
|
| 231 |
t.Logf("Blocks: %+v, \nOrder: %+v", blocks, order)
|
| 232 |
+
assert.Equal(t, uint64(12), blocks[1].BlockNumber)
|
| 233 |
assert.Equal(t, uint64(1), blocks[1].VerifiedBatches[0].BatchNumber)
|
| 234 |
assert.NotEqual(t, common.Address{}, blocks[1].VerifiedBatches[0].Aggregator)
|
| 235 |
assert.NotEqual(t, common.Hash{}, blocks[1].VerifiedBatches[0].TxHash)
|
|
|
|
| 241 |
|
| 242 |
func TestSequenceForceBatchesEvent(t *testing.T) {
|
| 243 |
// Set up testing environment
|
| 244 |
+
etherman, ethBackend, auth, _, _, _, _ := newTestingEnv(t)
|
| 245 |
|
| 246 |
// Read currentBlock
|
| 247 |
ctx := context.Background()
|
|
|
|
| 292 |
blocks, order, err := etherman.GetRollupInfoByBlockRange(ctx, initBlock.NumberU64(), &finalBlockNumber)
|
| 293 |
require.NoError(t, err)
|
| 294 |
t.Logf("Blocks: %+v", blocks)
|
| 295 |
+
assert.Equal(t, uint64(15), blocks[1].BlockNumber)
|
| 296 |
assert.Equal(t, uint64(2), blocks[1].SequencedForceBatches[0][0].BatchNumber)
|
| 297 |
assert.Equal(t, forcedGer, common.BytesToHash(blocks[1].SequencedForceBatches[0][0].ForcedGlobalExitRoot[:]))
|
| 298 |
assert.Equal(t, forcedTimestamp, blocks[1].SequencedForceBatches[0][0].ForcedTimestamp)
|
|
|
|
| 302 |
|
| 303 |
func TestSendSequences(t *testing.T) {
|
| 304 |
// Set up testing environment
|
| 305 |
+
etherman, ethBackend, auth, _, br, da, _ := newTestingEnv(t)
|
| 306 |
|
| 307 |
// Read currentBlock
|
| 308 |
ctx := context.Background()
|
|
|
|
| 324 |
BatchL2Data: batchL2Data,
|
| 325 |
LastL2BLockTimestamp: time.Now().Unix(),
|
| 326 |
}
|
| 327 |
+
daMessage, _ := hex.DecodeString("0x1234")
|
| 328 |
lastL2BlockTStamp := tx1.Time().Unix()
|
| 329 |
+
tx, err := etherman.sequenceBatches(*auth, []ethmanTypes.Sequence{sequence}, uint64(lastL2BlockTStamp), uint64(1), auth.From, daMessage)
|
|
|
|
| 330 |
require.NoError(t, err)
|
| 331 |
+
da.Mock.On("GetBatchL2Data", []uint64{2}, []common.Hash{crypto.Keccak256Hash(batchL2Data)}, daMessage).Return([][]byte{batchL2Data}, nil)
|
| 332 |
+
|
| 333 |
log.Debug("TX: ", tx.Hash())
|
| 334 |
ethBackend.Commit()
|
| 335 |
|
|
|
|
| 352 |
|
| 353 |
func TestGasPrice(t *testing.T) {
|
| 354 |
// Set up testing environment
|
| 355 |
+
etherman, _, _, _, _, _, _ := newTestingEnv(t)
|
| 356 |
etherscanM := new(etherscanMock)
|
| 357 |
ethGasStationM := new(ethGasStationMock)
|
| 358 |
etherman.GasProviders.Providers = []ethereum.GasPricer{etherman.EthClient, etherscanM, ethGasStationM}
|
|
|
|
| 371 |
|
| 372 |
func TestErrorEthGasStationPrice(t *testing.T) {
|
| 373 |
// Set up testing environment
|
| 374 |
+
etherman, _, _, _, _, _, _ := newTestingEnv(t)
|
| 375 |
ethGasStationM := new(ethGasStationMock)
|
| 376 |
etherman.GasProviders.Providers = []ethereum.GasPricer{etherman.EthClient, ethGasStationM}
|
| 377 |
ctx := context.Background()
|
| 378 |
|
| 379 |
ethGasStationM.On("SuggestGasPrice", ctx).Return(big.NewInt(0), fmt.Errorf("error getting gasPrice from ethGasStation"))
|
| 380 |
gp := etherman.GetL1GasPrice(ctx)
|
| 381 |
+
assert.Equal(t, big.NewInt(1263075579), gp)
|
| 382 |
|
| 383 |
etherscanM := new(etherscanMock)
|
| 384 |
etherman.GasProviders.Providers = []ethereum.GasPricer{etherman.EthClient, etherscanM, ethGasStationM}
|
|
|
|
| 390 |
|
| 391 |
func TestErrorEtherScanPrice(t *testing.T) {
|
| 392 |
// Set up testing environment
|
| 393 |
+
etherman, _, _, _, _, _, _ := newTestingEnv(t)
|
| 394 |
etherscanM := new(etherscanMock)
|
| 395 |
ethGasStationM := new(ethGasStationMock)
|
| 396 |
etherman.GasProviders.Providers = []ethereum.GasPricer{etherman.EthClient, etherscanM, ethGasStationM}
|
|
|
|
| 404 |
|
| 405 |
func TestGetForks(t *testing.T) {
|
| 406 |
// Set up testing environment
|
| 407 |
+
etherman, _, _, _, _, _, _ := newTestingEnv(t)
|
| 408 |
ctx := context.Background()
|
| 409 |
forks, err := etherman.GetForks(ctx, 0, 132)
|
| 410 |
require.NoError(t, err)
|
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package etherman
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"context"
|
| 5 |
+
|
| 6 |
+
"github.com/ethereum/go-ethereum/common"
|
| 7 |
+
"github.com/jackc/pgx/v4"
|
| 8 |
+
)
|
| 9 |
+
|
| 10 |
+
type dataAvailabilityProvider interface {
|
| 11 |
+
GetBatchL2Data(batchNum []uint64, hash []common.Hash, dataAvailabilityMessage []byte) ([][]byte, error)
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
type stateProvider interface {
|
| 15 |
+
GetForcedBatchDataByNumbers(ctx context.Context, batchNumbers []uint64, dbTx pgx.Tx) (map[uint64][]byte, error)
|
| 16 |
+
}
|
|
@@ -23,7 +24,7 @@
|
|
| 23 |
|
| 24 |
// NewSimulatedEtherman creates an etherman that uses a simulated blockchain. It's important to notice that the ChainID of the auth
|
| 25 |
// must be 1337. The address that holds the auth will have an initial balance of 10 ETH
|
| 26 |
-
func NewSimulatedEtherman(cfg Config, auth *bind.TransactOpts) (*Client, *simulated.Backend, common.Address, *polygonzkevmbridge.Polygonzkevmbridge, error) {
|
| 27 |
if auth == nil {
|
| 28 |
// read only client
|
| 29 |
return &Client{}, nil, common.Address{}, nil, nil
|
|
@@ -37,8 +38,26 @@
|
|
| 37 |
},
|
| 38 |
}
|
| 39 |
blockGasLimit := uint64(999999999999999999) //nolint:gomnd
|
|
|
|
| 40 |
client := simulated.NewBackend(genesisAlloc, simulated.WithBlockGasLimit(blockGasLimit))
|
| 41 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
// Deploy contracts
|
| 43 |
const polDecimalPlaces = 18
|
| 44 |
totalSupply, _ := new(big.Int).SetString("10000000000000000000000000000", 10) //nolint:gomnd
|
|
@@ -102,7 +121,7 @@
|
|
| 102 |
log.Error("error: ", err)
|
| 103 |
return nil, nil, common.Address{}, nil, err
|
| 104 |
}
|
| 105 |
-
br, err
|
| 106 |
if err != nil {
|
| 107 |
log.Error("error: ", err)
|
| 108 |
return nil, nil, common.Address{}, nil, err
|
|
@@ -182,6 +201,11 @@
|
|
| 182 |
return nil, nil, common.Address{}, nil, err
|
| 183 |
}
|
| 184 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 185 |
_, err = trueZkevm.SetForceBatchAddress(auth, common.Address{})
|
| 186 |
if err != nil {
|
| 187 |
log.Error("error: ", err)
|
|
@@ -199,6 +223,8 @@
|
|
| 199 |
SCAddresses: []common.Address{zkevmAddr, mockRollupManagerAddr, exitManagerAddr},
|
| 200 |
auth: map[common.Address]bind.TransactOpts{},
|
| 201 |
cfg: cfg,
|
|
|
|
|
|
|
| 202 |
}
|
| 203 |
err = c.AddOrReplaceAuth(*auth)
|
| 204 |
if err != nil {
|
|
|
|
| 24 |
|
| 25 |
// NewSimulatedEtherman creates an etherman that uses a simulated blockchain. It's important to notice that the ChainID of the auth
|
| 26 |
// must be 1337. The address that holds the auth will have an initial balance of 10 ETH
|
| 27 |
+
func NewSimulatedEtherman(cfg Config, auth *bind.TransactOpts, daBackend dataAvailabilityProvider, st stateProvider) (etherman *Client, ethBackend *simulated.Backend, polAddr common.Address, br *polygonzkevmbridge.Polygonzkevmbridge, err error) {
|
| 28 |
if auth == nil {
|
| 29 |
// read only client
|
| 30 |
return &Client{}, nil, common.Address{}, nil, nil
|
|
|
|
| 38 |
},
|
| 39 |
}
|
| 40 |
blockGasLimit := uint64(999999999999999999) //nolint:gomnd
|
| 41 |
+
// client := simulated.NewBackend(genesisAlloc, simulated.WithBlockGasLimit(blockGasLimit))
|
| 42 |
client := simulated.NewBackend(genesisAlloc, simulated.WithBlockGasLimit(blockGasLimit))
|
| 43 |
|
| 44 |
+
// DAC Setup
|
| 45 |
+
daAddr, _, da, err := polygondatacommittee.DeployPolygondatacommittee(auth, client.Client())
|
| 46 |
+
if err != nil {
|
| 47 |
+
return nil, nil, common.Address{}, nil, err
|
| 48 |
+
}
|
| 49 |
+
client.Commit()
|
| 50 |
+
_, err = da.Initialize(auth)
|
| 51 |
+
if err != nil {
|
| 52 |
+
return nil, nil, common.Address{}, nil, err
|
| 53 |
+
}
|
| 54 |
+
client.Commit()
|
| 55 |
+
_, err = da.SetupCommittee(auth, big.NewInt(0), []string{}, []byte{})
|
| 56 |
+
if err != nil {
|
| 57 |
+
return nil, nil, common.Address{}, nil, err
|
| 58 |
+
}
|
| 59 |
+
client.Commit()
|
| 60 |
+
|
| 61 |
// Deploy contracts
|
| 62 |
const polDecimalPlaces = 18
|
| 63 |
totalSupply, _ := new(big.Int).SetString("10000000000000000000000000000", 10) //nolint:gomnd
|
|
|
|
| 121 |
log.Error("error: ", err)
|
| 122 |
return nil, nil, common.Address{}, nil, err
|
| 123 |
}
|
| 124 |
+
br, err = polygonzkevmbridge.NewPolygonzkevmbridge(bridgeAddr, client.Client())
|
| 125 |
if err != nil {
|
| 126 |
log.Error("error: ", err)
|
| 127 |
return nil, nil, common.Address{}, nil, err
|
|
|
|
| 201 |
return nil, nil, common.Address{}, nil, err
|
| 202 |
}
|
| 203 |
|
| 204 |
+
_, err = trueZkevm.SetDataAvailabilityProtocol(auth, daAddr)
|
| 205 |
+
if err != nil {
|
| 206 |
+
log.Error("error: ", err)
|
| 207 |
+
return nil, nil, common.Address{}, nil, err
|
| 208 |
+
}
|
| 209 |
_, err = trueZkevm.SetForceBatchAddress(auth, common.Address{})
|
| 210 |
if err != nil {
|
| 211 |
log.Error("error: ", err)
|
|
|
|
| 223 |
SCAddresses: []common.Address{zkevmAddr, mockRollupManagerAddr, exitManagerAddr},
|
| 224 |
auth: map[common.Address]bind.TransactOpts{},
|
| 225 |
cfg: cfg,
|
| 226 |
+
da: daBackend,
|
| 227 |
+
state: st,
|
| 228 |
}
|
| 229 |
err = c.AddOrReplaceAuth(*auth)
|
| 230 |
if err != nil {
|
|
@@ -42,12 +42,17 @@
|
|
| 42 |
EventID_SynchronizerHalt EventID = "SYNCHRONIZER HALT"
|
| 43 |
// EventID_SequenceSenderHalt is triggered when the SequenceSender halts
|
| 44 |
EventID_SequenceSenderHalt EventID = "SEQUENCESENDER HALT"
|
|
|
|
|
|
|
|
|
|
| 45 |
// EventID_NodeOOC is triggered when an OOC at node level is detected
|
| 46 |
EventID_NodeOOC EventID = "NODE OOC"
|
| 47 |
// EventID_UsedZKCountersOverflow is triggered when used ZK counters exceeds remaining batch ZK counters
|
| 48 |
EventID_UsedZKCountersOverflow EventID = "USED ZKCOUNTERS OVERFLOW"
|
| 49 |
// EventID_ReservedZKCountersOverflow is triggered when reserved ZK counters exceeds remaining batch ZK counters
|
| 50 |
EventID_ReservedZKCountersOverflow EventID = "RESERVED ZKCOUNTERS OVERFLOW"
|
|
|
|
|
|
|
| 51 |
// Source_Node is the source of the event
|
| 52 |
Source_Node Source = "node"
|
| 53 |
|
|
|
|
| 42 |
EventID_SynchronizerHalt EventID = "SYNCHRONIZER HALT"
|
| 43 |
// EventID_SequenceSenderHalt is triggered when the SequenceSender halts
|
| 44 |
EventID_SequenceSenderHalt EventID = "SEQUENCESENDER HALT"
|
| 45 |
+
// EventID_UnsupportedPrecompile is triggered when the executor returns an unsupported precompile error
|
| 46 |
+
EventID_UnsupportedPrecompile EventID = "UNSUPPORTED PRECOMPILE"
|
| 47 |
+
|
| 48 |
// EventID_NodeOOC is triggered when an OOC at node level is detected
|
| 49 |
EventID_NodeOOC EventID = "NODE OOC"
|
| 50 |
// EventID_UsedZKCountersOverflow is triggered when used ZK counters exceeds remaining batch ZK counters
|
| 51 |
EventID_UsedZKCountersOverflow EventID = "USED ZKCOUNTERS OVERFLOW"
|
| 52 |
// EventID_ReservedZKCountersOverflow is triggered when reserved ZK counters exceeds remaining batch ZK counters
|
| 53 |
EventID_ReservedZKCountersOverflow EventID = "RESERVED ZKCOUNTERS OVERFLOW"
|
| 54 |
+
// EventID_InvalidInfoRoot is triggered when an invalid l1InfoRoot was synced
|
| 55 |
+
EventID_InvalidInfoRoot EventID = "INVALID INFOROOT"
|
| 56 |
// Source_Node is the source of the event
|
| 57 |
Source_Node Source = "node"
|
| 58 |
|
|
@@ -30,3 +30,6 @@
|
|
| 30 |
include:
|
| 31 |
- EXC0012 # EXC0012 revive: Annoying issue about not having a comment. The rare codebase has such comments
|
| 32 |
- EXC0014 # EXC0014 revive: Annoying issue about not having a comment. The rare codebase has such comments
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
include:
|
| 31 |
- EXC0012 # EXC0012 revive: Annoying issue about not having a comment. The rare codebase has such comments
|
| 32 |
- EXC0014 # EXC0014 revive: Annoying issue about not having a comment. The rare codebase has such comments
|
| 33 |
+
exclude-rules:
|
| 34 |
+
- path: cmd/policy.go
|
| 35 |
+
text: "unused"
|
|
@@ -22,9 +22,9 @@
|
|
| 22 |
github.com/prometheus/common v0.45.0
|
| 23 |
github.com/rubenv/sql-migrate v1.6.1
|
| 24 |
github.com/spf13/afero v1.11.0
|
| 25 |
-
github.com/spf13/viper v1.
|
| 26 |
github.com/stretchr/testify v1.8.4
|
| 27 |
-
github.com/umbracle/ethgo v0.1.
|
| 28 |
github.com/urfave/cli/v2 v2.26.0
|
| 29 |
go.uber.org/zap v1.26.0
|
| 30 |
golang.org/x/crypto v0.18.0
|
|
@@ -45,7 +45,7 @@
|
|
| 45 |
github.com/VictoriaMetrics/fastcache v1.12.1 // indirect
|
| 46 |
github.com/bahlo/generic-list-go v0.2.0 // indirect
|
| 47 |
github.com/beorn7/perks v1.0.1 // indirect
|
| 48 |
-
github.com/bits-and-blooms/bitset v1.
|
| 49 |
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
|
| 50 |
github.com/buger/jsonparser v1.1.1 // indirect
|
| 51 |
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
|
@@ -63,12 +63,12 @@
|
|
| 63 |
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
|
| 64 |
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
| 65 |
github.com/deckarep/golang-set/v2 v2.1.0 // indirect
|
| 66 |
-
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.
|
| 67 |
github.com/dlclark/regexp2 v1.7.0 // indirect
|
| 68 |
github.com/emirpasic/gods v1.18.1 // indirect
|
| 69 |
github.com/ethereum/c-kzg-4844 v0.4.0 // indirect
|
| 70 |
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect
|
| 71 |
-
github.com/fsnotify/fsnotify v1.
|
| 72 |
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect
|
| 73 |
github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 // indirect
|
| 74 |
github.com/getsentry/sentry-go v0.18.0 // indirect
|
|
@@ -101,6 +101,7 @@
|
|
| 101 |
github.com/jackc/puddle v1.3.0 // indirect
|
| 102 |
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
|
| 103 |
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
|
|
|
| 104 |
github.com/karrick/godirwalk v1.17.0 // indirect
|
| 105 |
github.com/kevinburke/ssh_config v1.2.0 // indirect
|
| 106 |
github.com/klauspost/compress v1.17.0 // indirect
|
|
@@ -116,6 +117,7 @@
|
|
| 116 |
github.com/mattn/go-isatty v0.0.20 // indirect
|
| 117 |
github.com/mattn/go-runewidth v0.0.13 // indirect
|
| 118 |
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
|
|
|
|
| 119 |
github.com/mitchellh/pointerstructure v1.2.0 // indirect
|
| 120 |
github.com/mmcloughlin/addchain v0.4.0 // indirect
|
| 121 |
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
|
@@ -128,14 +130,14 @@
|
|
| 128 |
github.com/rogpeppe/go-internal v1.11.0 // indirect
|
| 129 |
github.com/rs/cors v1.7.0 // indirect
|
| 130 |
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
| 131 |
-
github.com/sagikazarmark/locafero v0.
|
| 132 |
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
| 133 |
github.com/sergi/go-diff v1.2.0 // indirect
|
| 134 |
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect
|
| 135 |
github.com/sirupsen/logrus v1.9.0 // indirect
|
| 136 |
github.com/skeema/knownhosts v1.2.1 // indirect
|
| 137 |
github.com/sourcegraph/conc v0.3.0 // indirect
|
| 138 |
-
github.com/spf13/cast v1.
|
| 139 |
github.com/spf13/pflag v1.0.5 // indirect
|
| 140 |
github.com/status-im/keycard-go v0.2.0 // indirect
|
| 141 |
github.com/stretchr/objx v0.5.0 // indirect
|
|
@@ -170,8 +172,9 @@
|
|
| 170 |
)
|
| 171 |
|
| 172 |
require (
|
|
|
|
|
|
|
| 173 |
github.com/fatih/color v1.16.0
|
| 174 |
-
github.com/joho/godotenv v1.5.1
|
| 175 |
github.com/prometheus/client_golang v1.18.0
|
| 176 |
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
|
| 177 |
)
|
|
|
|
| 22 |
github.com/prometheus/common v0.45.0
|
| 23 |
github.com/rubenv/sql-migrate v1.6.1
|
| 24 |
github.com/spf13/afero v1.11.0
|
| 25 |
+
github.com/spf13/viper v1.18.2
|
| 26 |
github.com/stretchr/testify v1.8.4
|
| 27 |
+
github.com/umbracle/ethgo v0.1.4-0.20230712173909-df37dddf16f0
|
| 28 |
github.com/urfave/cli/v2 v2.26.0
|
| 29 |
go.uber.org/zap v1.26.0
|
| 30 |
golang.org/x/crypto v0.18.0
|
|
|
|
| 45 |
github.com/VictoriaMetrics/fastcache v1.12.1 // indirect
|
| 46 |
github.com/bahlo/generic-list-go v0.2.0 // indirect
|
| 47 |
github.com/beorn7/perks v1.0.1 // indirect
|
| 48 |
+
github.com/bits-and-blooms/bitset v1.12.0 // indirect
|
| 49 |
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
|
| 50 |
github.com/buger/jsonparser v1.1.1 // indirect
|
| 51 |
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
|
|
|
| 63 |
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
|
| 64 |
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
| 65 |
github.com/deckarep/golang-set/v2 v2.1.0 // indirect
|
| 66 |
+
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
|
| 67 |
github.com/dlclark/regexp2 v1.7.0 // indirect
|
| 68 |
github.com/emirpasic/gods v1.18.1 // indirect
|
| 69 |
github.com/ethereum/c-kzg-4844 v0.4.0 // indirect
|
| 70 |
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect
|
| 71 |
+
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
| 72 |
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect
|
| 73 |
github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 // indirect
|
| 74 |
github.com/getsentry/sentry-go v0.18.0 // indirect
|
|
|
|
| 101 |
github.com/jackc/puddle v1.3.0 // indirect
|
| 102 |
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
|
| 103 |
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
| 104 |
+
github.com/jmoiron/sqlx v1.2.0 // indirect
|
| 105 |
github.com/karrick/godirwalk v1.17.0 // indirect
|
| 106 |
github.com/kevinburke/ssh_config v1.2.0 // indirect
|
| 107 |
github.com/klauspost/compress v1.17.0 // indirect
|
|
|
|
| 117 |
github.com/mattn/go-isatty v0.0.20 // indirect
|
| 118 |
github.com/mattn/go-runewidth v0.0.13 // indirect
|
| 119 |
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
|
| 120 |
+
github.com/miguelmota/go-solidity-sha3 v0.1.1 // indirect
|
| 121 |
github.com/mitchellh/pointerstructure v1.2.0 // indirect
|
| 122 |
github.com/mmcloughlin/addchain v0.4.0 // indirect
|
| 123 |
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
|
|
|
| 130 |
github.com/rogpeppe/go-internal v1.11.0 // indirect
|
| 131 |
github.com/rs/cors v1.7.0 // indirect
|
| 132 |
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
| 133 |
+
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
| 134 |
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
| 135 |
github.com/sergi/go-diff v1.2.0 // indirect
|
| 136 |
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect
|
| 137 |
github.com/sirupsen/logrus v1.9.0 // indirect
|
| 138 |
github.com/skeema/knownhosts v1.2.1 // indirect
|
| 139 |
github.com/sourcegraph/conc v0.3.0 // indirect
|
| 140 |
+
github.com/spf13/cast v1.6.0 // indirect
|
| 141 |
github.com/spf13/pflag v1.0.5 // indirect
|
| 142 |
github.com/status-im/keycard-go v0.2.0 // indirect
|
| 143 |
github.com/stretchr/objx v0.5.0 // indirect
|
|
|
|
| 172 |
)
|
| 173 |
|
| 174 |
require (
|
| 175 |
+
github.com/0xPolygon/agglayer v0.0.1
|
| 176 |
+
github.com/0xPolygon/cdk-data-availability v0.0.5
|
| 177 |
github.com/fatih/color v1.16.0
|
|
|
|
| 178 |
github.com/prometheus/client_golang v1.18.0
|
| 179 |
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
|
| 180 |
)
|
|
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# .goreleaser-cdk.yaml
|
| 2 |
+
project_name: cdk-validium-node
|
| 3 |
+
|
| 4 |
+
release:
|
| 5 |
+
disable: false
|
| 6 |
+
draft: true
|
| 7 |
+
prerelease: auto
|
| 8 |
+
|
| 9 |
+
before:
|
| 10 |
+
hooks:
|
| 11 |
+
- go mod download
|
| 12 |
+
- go install github.com/gobuffalo/packr/v2/packr2@v2.8.3
|
| 13 |
+
- packr2
|
| 14 |
+
|
| 15 |
+
builds:
|
| 16 |
+
- main: ./cmd/
|
| 17 |
+
binary: zkevm-node
|
| 18 |
+
goos:
|
| 19 |
+
- linux
|
| 20 |
+
- darwin
|
| 21 |
+
goarch:
|
| 22 |
+
- amd64
|
| 23 |
+
- arm64
|
| 24 |
+
env:
|
| 25 |
+
- CGO_ENABLED=0
|
| 26 |
+
ldflags:
|
| 27 |
+
- -s -w
|
| 28 |
+
- -X github.com/0xPolygonHermez/zkevm-node.Version={{ .Version }}
|
| 29 |
+
- -X github.com/0xPolygonHermez/zkevm-node.GitRev={{ .Commit }}
|
| 30 |
+
- -X github.com/0xPolygonHermez/zkevm-node.BuildDate={{ .Date }}
|
| 31 |
+
- -X github.com/0xPolygonHermez/zkevm-node.GitBranch={{ .Branch }}
|
| 32 |
+
|
| 33 |
+
archives:
|
| 34 |
+
- files:
|
| 35 |
+
- LICENSE
|
| 36 |
+
- README.md
|
| 37 |
+
|
| 38 |
+
dockers:
|
| 39 |
+
- image_templates:
|
| 40 |
+
- 0xpolygon/{{ .ProjectName }}:{{ replace .Version "+" "-" }}-amd64
|
| 41 |
+
dockerfile: Dockerfile.release
|
| 42 |
+
use: buildx
|
| 43 |
+
goos: linux
|
| 44 |
+
goarch: amd64
|
| 45 |
+
build_flag_templates:
|
| 46 |
+
- --platform=linux/amd64
|
| 47 |
+
- --label=org.opencontainers.image.title={{ .ProjectName }}
|
| 48 |
+
- --label=org.opencontainers.image.description={{ .ProjectName }}
|
| 49 |
+
- --label=org.opencontainers.image.url=https://github.com/{{ .ProjectName }}
|
| 50 |
+
- --label=org.opencontainers.image.source=https://github.com/{{ .ProjectName }}
|
| 51 |
+
- --label=org.opencontainers.image.version={{ replace .Version "+" "-" }}
|
| 52 |
+
- --label=org.opencontainers.image.created={{ time "2006-01-02T15:04:05Z07:00" }}
|
| 53 |
+
- --label=org.opencontainers.image.revision={{ .FullCommit }}
|
| 54 |
+
skip_push: false
|
| 55 |
+
|
| 56 |
+
- image_templates:
|
| 57 |
+
- 0xpolygon/{{ .ProjectName }}:{{ replace .Version "+" "-" }}-arm64
|
| 58 |
+
dockerfile: Dockerfile.release
|
| 59 |
+
use: buildx
|
| 60 |
+
goos: linux
|
| 61 |
+
goarch: arm64
|
| 62 |
+
build_flag_templates:
|
| 63 |
+
- --platform=linux/arm64
|
| 64 |
+
- --label=org.opencontainers.image.title={{ .ProjectName }}
|
| 65 |
+
- --label=org.opencontainers.image.description={{ .ProjectName }}
|
| 66 |
+
- --label=org.opencontainers.image.url=https://github.com/{{ .ProjectName }}
|
| 67 |
+
- --label=org.opencontainers.image.source=https://github.com/{{ .ProjectName }}
|
| 68 |
+
- --label=org.opencontainers.image.version={{ replace .Version "+" "-" }}
|
| 69 |
+
- --label=org.opencontainers.image.created={{ time "2006-01-02T15:04:05Z07:00" }}
|
| 70 |
+
- --label=org.opencontainers.image.revision={{ .FullCommit }}
|
| 71 |
+
skip_push: false
|
| 72 |
+
|
| 73 |
+
docker_manifests:
|
| 74 |
+
- name_template: 0xpolygon/{{ .ProjectName }}:{{ replace .Version "+" "-" }}
|
| 75 |
+
image_templates:
|
| 76 |
+
- 0xpolygon/{{ .ProjectName }}:{{ replace .Version "+" "-" }}-amd64
|
| 77 |
+
- 0xpolygon/{{ .ProjectName }}:{{ replace .Version "+" "-" }}-arm64
|
| 78 |
+
skip_push: false
|
| 79 |
+
|
| 80 |
+
- name_template: 0xpolygon/{{ .ProjectName }}:latest
|
| 81 |
+
image_templates:
|
| 82 |
+
- 0xpolygon/{{ .ProjectName }}:{{ replace .Version "+" "-" }}-amd64
|
| 83 |
+
- 0xpolygon/{{ .ProjectName }}:{{ replace .Version "+" "-" }}-arm64
|
| 84 |
+
skip_push: false
|
|
@@ -58,6 +58,46 @@
|
|
| 58 |
return result, nil
|
| 59 |
}
|
| 60 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 61 |
// ExitRootsByGER returns the exit roots accordingly to the provided Global Exit Root
|
| 62 |
func (c *Client) ExitRootsByGER(ctx context.Context, globalExitRoot common.Hash) (*types.ExitRoots, error) {
|
| 63 |
response, err := JSONRPCCall(c.url, "zkevm_getExitRootsByGER", globalExitRoot.String())
|
|
|
|
| 58 |
return result, nil
|
| 59 |
}
|
| 60 |
|
| 61 |
+
// BatchesByNumbers returns batches from the current canonical chain by batch numbers. If the list is empty, the last
|
| 62 |
+
// known batch is returned as a list.
|
| 63 |
+
func (c *Client) BatchesByNumbers(ctx context.Context, numbers []*big.Int) ([]*types.BatchData, error) {
|
| 64 |
+
return c.batchesByNumbers(ctx, numbers, "zkevm_getBatchDataByNumbers")
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
// ForcedBatchesByNumbers returns forced batches data.
|
| 68 |
+
func (c *Client) ForcedBatchesByNumbers(ctx context.Context, numbers []*big.Int) ([]*types.BatchData, error) {
|
| 69 |
+
return c.batchesByNumbers(ctx, numbers, "zkevm_getForcedBatchDataByNumbers")
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
// BatchesByNumbers returns batches from the current canonical chain by batch numbers. If the list is empty, the last
|
| 73 |
+
// known batch is returned as a list.
|
| 74 |
+
func (c *Client) batchesByNumbers(_ context.Context, numbers []*big.Int, method string) ([]*types.BatchData, error) {
|
| 75 |
+
batchNumbers := make([]types.BatchNumber, 0, len(numbers))
|
| 76 |
+
for _, n := range numbers {
|
| 77 |
+
batchNumbers = append(batchNumbers, types.BatchNumber(n.Int64()))
|
| 78 |
+
}
|
| 79 |
+
if len(batchNumbers) == 0 {
|
| 80 |
+
batchNumbers = append(batchNumbers, types.LatestBatchNumber)
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
response, err := JSONRPCCall(c.url, method, &types.BatchFilter{Numbers: batchNumbers})
|
| 84 |
+
if err != nil {
|
| 85 |
+
return nil, err
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
if response.Error != nil {
|
| 89 |
+
return nil, response.Error.RPCError()
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
var result *types.BatchDataResult
|
| 93 |
+
err = json.Unmarshal(response.Result, &result)
|
| 94 |
+
if err != nil {
|
| 95 |
+
return nil, err
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
return result.Data, nil
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
// ExitRootsByGER returns the exit roots accordingly to the provided Global Exit Root
|
| 102 |
func (c *Client) ExitRootsByGER(ctx context.Context, globalExitRoot common.Hash) (*types.ExitRoots, error) {
|
| 103 |
response, err := JSONRPCCall(c.url, "zkevm_getExitRootsByGER", globalExitRoot.String())
|
|
@@ -68,8 +68,6 @@
|
|
| 68 |
return e.txMan.NewDbTxScope(e.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) {
|
| 69 |
if arg == nil {
|
| 70 |
return RPCErrorResponse(types.InvalidParamsErrorCode, "missing value for required argument 0", nil, false)
|
| 71 |
-
} else if blockArg == nil {
|
| 72 |
-
return RPCErrorResponse(types.InvalidParamsErrorCode, "missing value for required argument 1", nil, false)
|
| 73 |
}
|
| 74 |
block, respErr := e.getBlockByArg(ctx, blockArg, dbTx)
|
| 75 |
if respErr != nil {
|
|
@@ -106,13 +104,16 @@
|
|
| 106 |
result, err := e.state.ProcessUnsignedTransaction(ctx, tx, sender, blockToProcess, true, dbTx)
|
| 107 |
if err != nil {
|
| 108 |
errMsg := fmt.Sprintf("failed to execute the unsigned transaction: %v", err.Error())
|
| 109 |
-
logError := !executor.IsROMOutOfCountersError(executor.RomErrorCode(err)) && !errors.Is(err, runtime.ErrOutOfGas)
|
| 110 |
return RPCErrorResponse(types.DefaultErrorCode, errMsg, nil, logError)
|
| 111 |
}
|
| 112 |
|
| 113 |
if result.Reverted() {
|
| 114 |
data := make([]byte, len(result.ReturnValue))
|
| 115 |
copy(data, result.ReturnValue)
|
|
|
|
|
|
|
|
|
|
| 116 |
return nil, types.NewRPCErrorWithData(types.RevertedErrorCode, result.Err.Error(), data)
|
| 117 |
} else if result.Failed() {
|
| 118 |
return nil, types.NewRPCError(types.DefaultErrorCode, result.Err.Error())
|
|
@@ -191,6 +192,9 @@
|
|
| 191 |
if errors.Is(err, runtime.ErrExecutionReverted) {
|
| 192 |
data := make([]byte, len(returnValue))
|
| 193 |
copy(data, returnValue)
|
|
|
|
|
|
|
|
|
|
| 194 |
return nil, types.NewRPCErrorWithData(types.RevertedErrorCode, err.Error(), data)
|
| 195 |
} else if err != nil {
|
| 196 |
return nil, types.NewRPCError(types.DefaultErrorCode, err.Error())
|
|
@@ -941,6 +945,9 @@
|
|
| 941 |
if e.cfg.SequencerNodeURI != "" {
|
| 942 |
return e.relayTxToSequencerNode(input)
|
| 943 |
} else {
|
|
|
|
|
|
|
|
|
|
| 944 |
ip := ""
|
| 945 |
ips := httpRequest.Header.Get("X-Forwarded-For")
|
| 946 |
|
|
|
|
| 68 |
return e.txMan.NewDbTxScope(e.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) {
|
| 69 |
if arg == nil {
|
| 70 |
return RPCErrorResponse(types.InvalidParamsErrorCode, "missing value for required argument 0", nil, false)
|
|
|
|
|
|
|
| 71 |
}
|
| 72 |
block, respErr := e.getBlockByArg(ctx, blockArg, dbTx)
|
| 73 |
if respErr != nil {
|
|
|
|
| 104 |
result, err := e.state.ProcessUnsignedTransaction(ctx, tx, sender, blockToProcess, true, dbTx)
|
| 105 |
if err != nil {
|
| 106 |
errMsg := fmt.Sprintf("failed to execute the unsigned transaction: %v", err.Error())
|
| 107 |
+
logError := !executor.IsROMOutOfCountersError(executor.RomErrorCode(err)) && !(errors.Is(err, runtime.ErrOutOfGas))
|
| 108 |
return RPCErrorResponse(types.DefaultErrorCode, errMsg, nil, logError)
|
| 109 |
}
|
| 110 |
|
| 111 |
if result.Reverted() {
|
| 112 |
data := make([]byte, len(result.ReturnValue))
|
| 113 |
copy(data, result.ReturnValue)
|
| 114 |
+
if len(data) == 0 {
|
| 115 |
+
return nil, types.NewRPCError(types.DefaultErrorCode, result.Err.Error())
|
| 116 |
+
}
|
| 117 |
return nil, types.NewRPCErrorWithData(types.RevertedErrorCode, result.Err.Error(), data)
|
| 118 |
} else if result.Failed() {
|
| 119 |
return nil, types.NewRPCError(types.DefaultErrorCode, result.Err.Error())
|
|
|
|
| 192 |
if errors.Is(err, runtime.ErrExecutionReverted) {
|
| 193 |
data := make([]byte, len(returnValue))
|
| 194 |
copy(data, returnValue)
|
| 195 |
+
if len(data) == 0 {
|
| 196 |
+
return nil, types.NewRPCError(types.DefaultErrorCode, err.Error())
|
| 197 |
+
}
|
| 198 |
return nil, types.NewRPCErrorWithData(types.RevertedErrorCode, err.Error(), data)
|
| 199 |
} else if err != nil {
|
| 200 |
return nil, types.NewRPCError(types.DefaultErrorCode, err.Error())
|
|
|
|
| 945 |
if e.cfg.SequencerNodeURI != "" {
|
| 946 |
return e.relayTxToSequencerNode(input)
|
| 947 |
} else {
|
| 948 |
+
if err := checkPolicy(context.Background(), e.pool, input); err != nil {
|
| 949 |
+
return RPCErrorResponse(types.AccessDeniedCode, err.Error(), nil, false)
|
| 950 |
+
}
|
| 951 |
ip := ""
|
| 952 |
ips := httpRequest.Header.Get("X-Forwarded-For")
|
| 953 |
|
|
@@ -6,6 +6,7 @@
|
|
| 6 |
"errors"
|
| 7 |
"fmt"
|
| 8 |
"math/big"
|
|
|
|
| 9 |
"sync"
|
| 10 |
"testing"
|
| 11 |
"time"
|
|
@@ -503,7 +504,7 @@
|
|
| 503 |
latest,
|
| 504 |
},
|
| 505 |
expectedResult: nil,
|
| 506 |
-
expectedError: types.NewRPCError(types.
|
| 507 |
setupMocks: func(c Config, m *mocksWrapper, testCase *testCase) {
|
| 508 |
nonce := uint64(7)
|
| 509 |
m.DbTx.On("Rollback", context.Background()).Return(nil).Once()
|
|
@@ -5416,3 +5417,237 @@
|
|
| 5416 |
assert.ElementsMatch(t, []int{13, 14, 15}, results[4])
|
| 5417 |
assert.ElementsMatch(t, []int{16}, results[5])
|
| 5418 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
"errors"
|
| 7 |
"fmt"
|
| 8 |
"math/big"
|
| 9 |
+
"strings"
|
| 10 |
"sync"
|
| 11 |
"testing"
|
| 12 |
"time"
|
|
|
|
| 504 |
latest,
|
| 505 |
},
|
| 506 |
expectedResult: nil,
|
| 507 |
+
expectedError: types.NewRPCError(types.DefaultErrorCode, "execution reverted"),
|
| 508 |
setupMocks: func(c Config, m *mocksWrapper, testCase *testCase) {
|
| 509 |
nonce := uint64(7)
|
| 510 |
m.DbTx.On("Rollback", context.Background()).Return(nil).Once()
|
|
|
|
| 5417 |
assert.ElementsMatch(t, []int{13, 14, 15}, results[4])
|
| 5418 |
assert.ElementsMatch(t, []int{16}, results[5])
|
| 5419 |
}
|
| 5420 |
+
|
| 5421 |
+
func TestSendRawTransactionJSONRPCCallWithPolicyApplied(t *testing.T) {
|
| 5422 |
+
// Set up the sender
|
| 5423 |
+
allowedPrivateKey, err := crypto.HexToECDSA(strings.TrimPrefix("0x28b2b0318721be8c8339199172cd7cc8f5e273800a35616ec893083a4b32c02e", "0x"))
|
| 5424 |
+
require.NoError(t, err)
|
| 5425 |
+
allowed, err := bind.NewKeyedTransactorWithChainID(allowedPrivateKey, big.NewInt(1))
|
| 5426 |
+
require.NoError(t, err)
|
| 5427 |
+
|
| 5428 |
+
disallowedPrivateKey, err := crypto.HexToECDSA(strings.TrimPrefix("0xdeadbeef8721be8c8339199172cd7cc8f5e273800a35616ec893083a4b32c02e", "0x"))
|
| 5429 |
+
require.NoError(t, err)
|
| 5430 |
+
disallowed, err := bind.NewKeyedTransactorWithChainID(disallowedPrivateKey, big.NewInt(1))
|
| 5431 |
+
require.NoError(t, err)
|
| 5432 |
+
require.NotNil(t, disallowed)
|
| 5433 |
+
|
| 5434 |
+
allowedContract := common.HexToAddress("0x1")
|
| 5435 |
+
disallowedContract := common.HexToAddress("0x2")
|
| 5436 |
+
|
| 5437 |
+
senderDenied := types.NewRPCError(types.AccessDeniedCode, "sender disallowed send_tx by policy")
|
| 5438 |
+
contractDenied := types.NewRPCError(types.AccessDeniedCode, "contract disallowed send_tx by policy")
|
| 5439 |
+
deployDenied := types.NewRPCError(types.AccessDeniedCode, "sender disallowed deploy by policy")
|
| 5440 |
+
|
| 5441 |
+
cfg := getSequencerDefaultConfig()
|
| 5442 |
+
s, m, _ := newMockedServerWithCustomConfig(t, cfg)
|
| 5443 |
+
defer s.Stop()
|
| 5444 |
+
|
| 5445 |
+
type testCase struct {
|
| 5446 |
+
Name string
|
| 5447 |
+
Input string
|
| 5448 |
+
ExpectedResult *common.Hash
|
| 5449 |
+
ExpectedError types.Error
|
| 5450 |
+
Prepare func(t *testing.T, tc *testCase)
|
| 5451 |
+
SetupMocks func(t *testing.T, m *mocksWrapper, tc testCase)
|
| 5452 |
+
}
|
| 5453 |
+
|
| 5454 |
+
testCases := []testCase{
|
| 5455 |
+
{
|
| 5456 |
+
Name: "Sender & contract on allow list, accepted",
|
| 5457 |
+
Prepare: func(t *testing.T, tc *testCase) {
|
| 5458 |
+
tx := ethTypes.NewTransaction(1, allowedContract, big.NewInt(1), uint64(1), big.NewInt(1), []byte{})
|
| 5459 |
+
|
| 5460 |
+
signedTx, err := allowed.Signer(allowed.From, tx)
|
| 5461 |
+
require.NoError(t, err)
|
| 5462 |
+
|
| 5463 |
+
txBinary, err := signedTx.MarshalBinary()
|
| 5464 |
+
require.NoError(t, err)
|
| 5465 |
+
|
| 5466 |
+
rawTx := hex.EncodeToHex(txBinary)
|
| 5467 |
+
require.NoError(t, err)
|
| 5468 |
+
|
| 5469 |
+
tc.Input = rawTx
|
| 5470 |
+
expectedHash := signedTx.Hash()
|
| 5471 |
+
tc.ExpectedResult = &expectedHash
|
| 5472 |
+
tc.ExpectedError = nil
|
| 5473 |
+
},
|
| 5474 |
+
SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) {
|
| 5475 |
+
m.Pool.
|
| 5476 |
+
On("AddTx", context.Background(), mock.IsType(ethTypes.Transaction{}), "").
|
| 5477 |
+
Return(nil).
|
| 5478 |
+
Once()
|
| 5479 |
+
m.Pool.
|
| 5480 |
+
On("CheckPolicy", context.Background(), pool.SendTx, allowedContract).
|
| 5481 |
+
Return(true, nil).
|
| 5482 |
+
Once()
|
| 5483 |
+
m.Pool.
|
| 5484 |
+
On("CheckPolicy", context.Background(), pool.SendTx, allowed.From).
|
| 5485 |
+
Return(true, nil).
|
| 5486 |
+
Once()
|
| 5487 |
+
},
|
| 5488 |
+
},
|
| 5489 |
+
{
|
| 5490 |
+
Name: "Contract not on allow list, rejected",
|
| 5491 |
+
Prepare: func(t *testing.T, tc *testCase) {
|
| 5492 |
+
tx := ethTypes.NewTransaction(1, disallowedContract, big.NewInt(1), uint64(1), big.NewInt(1), []byte{})
|
| 5493 |
+
|
| 5494 |
+
signedTx, err := allowed.Signer(allowed.From, tx)
|
| 5495 |
+
require.NoError(t, err)
|
| 5496 |
+
|
| 5497 |
+
txBinary, err := signedTx.MarshalBinary()
|
| 5498 |
+
require.NoError(t, err)
|
| 5499 |
+
|
| 5500 |
+
rawTx := hex.EncodeToHex(txBinary)
|
| 5501 |
+
require.NoError(t, err)
|
| 5502 |
+
|
| 5503 |
+
tc.Input = rawTx
|
| 5504 |
+
tc.ExpectedResult = nil
|
| 5505 |
+
tc.ExpectedError = contractDenied
|
| 5506 |
+
},
|
| 5507 |
+
SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) {
|
| 5508 |
+
m.Pool.
|
| 5509 |
+
On("CheckPolicy", context.Background(), pool.SendTx, disallowedContract).
|
| 5510 |
+
Return(false, contractDenied).
|
| 5511 |
+
Once()
|
| 5512 |
+
},
|
| 5513 |
+
},
|
| 5514 |
+
{
|
| 5515 |
+
Name: "Sender not on allow list, rejected",
|
| 5516 |
+
Prepare: func(t *testing.T, tc *testCase) {
|
| 5517 |
+
tx := ethTypes.NewTransaction(1, allowedContract, big.NewInt(1), uint64(1), big.NewInt(1), []byte{})
|
| 5518 |
+
|
| 5519 |
+
signedTx, err := disallowed.Signer(disallowed.From, tx)
|
| 5520 |
+
require.NoError(t, err)
|
| 5521 |
+
|
| 5522 |
+
txBinary, err := signedTx.MarshalBinary()
|
| 5523 |
+
require.NoError(t, err)
|
| 5524 |
+
|
| 5525 |
+
rawTx := hex.EncodeToHex(txBinary)
|
| 5526 |
+
require.NoError(t, err)
|
| 5527 |
+
|
| 5528 |
+
tc.Input = rawTx
|
| 5529 |
+
tc.ExpectedResult = nil
|
| 5530 |
+
tc.ExpectedError = senderDenied
|
| 5531 |
+
},
|
| 5532 |
+
SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) {
|
| 5533 |
+
m.Pool.
|
| 5534 |
+
On("CheckPolicy", context.Background(), pool.SendTx, allowedContract).
|
| 5535 |
+
Return(true, nil).
|
| 5536 |
+
Once()
|
| 5537 |
+
m.Pool.
|
| 5538 |
+
On("CheckPolicy", context.Background(), pool.SendTx, disallowed.From).
|
| 5539 |
+
Return(false, senderDenied).
|
| 5540 |
+
Once()
|
| 5541 |
+
},
|
| 5542 |
+
},
|
| 5543 |
+
{
|
| 5544 |
+
Name: "Unsigned tx with allowed contract, accepted", // for backward compatibility
|
| 5545 |
+
Prepare: func(t *testing.T, tc *testCase) {
|
| 5546 |
+
tx := ethTypes.NewTransaction(1, allowedContract, big.NewInt(1), uint64(1), big.NewInt(1), []byte{})
|
| 5547 |
+
|
| 5548 |
+
txBinary, err := tx.MarshalBinary()
|
| 5549 |
+
require.NoError(t, err)
|
| 5550 |
+
|
| 5551 |
+
rawTx := hex.EncodeToHex(txBinary)
|
| 5552 |
+
require.NoError(t, err)
|
| 5553 |
+
|
| 5554 |
+
tc.Input = rawTx
|
| 5555 |
+
expectedHash := tx.Hash()
|
| 5556 |
+
tc.ExpectedResult = &expectedHash
|
| 5557 |
+
tc.ExpectedError = nil
|
| 5558 |
+
},
|
| 5559 |
+
SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) {
|
| 5560 |
+
m.Pool.
|
| 5561 |
+
On("AddTx", context.Background(), mock.IsType(ethTypes.Transaction{}), "").
|
| 5562 |
+
Return(nil).
|
| 5563 |
+
Once()
|
| 5564 |
+
// policy does not reject this case for backward compat
|
| 5565 |
+
},
|
| 5566 |
+
},
|
| 5567 |
+
{
|
| 5568 |
+
Name: "Unsigned tx with disallowed contract, rejected",
|
| 5569 |
+
Prepare: func(t *testing.T, tc *testCase) {
|
| 5570 |
+
tx := ethTypes.NewTransaction(1, disallowedContract, big.NewInt(1), uint64(1), big.NewInt(1), []byte{})
|
| 5571 |
+
|
| 5572 |
+
signedTx, err := disallowed.Signer(disallowed.From, tx)
|
| 5573 |
+
require.NoError(t, err)
|
| 5574 |
+
|
| 5575 |
+
txBinary, err := signedTx.MarshalBinary()
|
| 5576 |
+
require.NoError(t, err)
|
| 5577 |
+
|
| 5578 |
+
rawTx := hex.EncodeToHex(txBinary)
|
| 5579 |
+
require.NoError(t, err)
|
| 5580 |
+
|
| 5581 |
+
tc.Input = rawTx
|
| 5582 |
+
tc.ExpectedResult = nil
|
| 5583 |
+
tc.ExpectedError = contractDenied
|
| 5584 |
+
},
|
| 5585 |
+
SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) {
|
| 5586 |
+
m.Pool.
|
| 5587 |
+
On("CheckPolicy", context.Background(), pool.SendTx, disallowedContract).
|
| 5588 |
+
Return(false, contractDenied).
|
| 5589 |
+
Once()
|
| 5590 |
+
},
|
| 5591 |
+
},
|
| 5592 |
+
{
|
| 5593 |
+
Name: "Send invalid tx input", // for backward compatibility
|
| 5594 |
+
Prepare: func(t *testing.T, tc *testCase) {
|
| 5595 |
+
tc.Input = "0x1234"
|
| 5596 |
+
tc.ExpectedResult = nil
|
| 5597 |
+
tc.ExpectedError = types.NewRPCError(types.InvalidParamsErrorCode, "invalid tx input")
|
| 5598 |
+
},
|
| 5599 |
+
SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) {},
|
| 5600 |
+
},
|
| 5601 |
+
{
|
| 5602 |
+
Name: "Sender not on deploy allow list, rejected",
|
| 5603 |
+
Prepare: func(t *testing.T, tc *testCase) {
|
| 5604 |
+
deployAddr := common.HexToAddress("0x0")
|
| 5605 |
+
tx := ethTypes.NewTransaction(1, deployAddr, big.NewInt(1), uint64(1), big.NewInt(1), []byte{})
|
| 5606 |
+
|
| 5607 |
+
signedTx, err := disallowed.Signer(disallowed.From, tx)
|
| 5608 |
+
require.NoError(t, err)
|
| 5609 |
+
|
| 5610 |
+
txBinary, err := signedTx.MarshalBinary()
|
| 5611 |
+
require.NoError(t, err)
|
| 5612 |
+
|
| 5613 |
+
rawTx := hex.EncodeToHex(txBinary)
|
| 5614 |
+
require.NoError(t, err)
|
| 5615 |
+
|
| 5616 |
+
tc.Input = rawTx
|
| 5617 |
+
tc.ExpectedResult = nil
|
| 5618 |
+
tc.ExpectedError = deployDenied
|
| 5619 |
+
},
|
| 5620 |
+
SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) {
|
| 5621 |
+
m.Pool.
|
| 5622 |
+
On("CheckPolicy", context.Background(), pool.Deploy, disallowed.From).
|
| 5623 |
+
Return(false, nil).
|
| 5624 |
+
Once()
|
| 5625 |
+
},
|
| 5626 |
+
},
|
| 5627 |
+
}
|
| 5628 |
+
|
| 5629 |
+
for _, testCase := range testCases {
|
| 5630 |
+
t.Run(testCase.Name, func(t *testing.T) {
|
| 5631 |
+
tc := testCase
|
| 5632 |
+
tc.Prepare(t, &tc)
|
| 5633 |
+
tc.SetupMocks(t, m, tc)
|
| 5634 |
+
|
| 5635 |
+
res, err := s.JSONRPCCall("eth_sendRawTransaction", tc.Input)
|
| 5636 |
+
require.NoError(t, err)
|
| 5637 |
+
|
| 5638 |
+
assert.Equal(t, float64(1), res.ID)
|
| 5639 |
+
assert.Equal(t, "2.0", res.JSONRPC)
|
| 5640 |
+
|
| 5641 |
+
if res.Result != nil || tc.ExpectedResult != nil {
|
| 5642 |
+
var result common.Hash
|
| 5643 |
+
err = json.Unmarshal(res.Result, &result)
|
| 5644 |
+
require.NoError(t, err)
|
| 5645 |
+
assert.Equal(t, *tc.ExpectedResult, result)
|
| 5646 |
+
}
|
| 5647 |
+
if res.Error != nil || tc.ExpectedError != nil {
|
| 5648 |
+
assert.Equal(t, tc.ExpectedError.ErrorCode(), res.Error.Code)
|
| 5649 |
+
assert.Equal(t, tc.ExpectedError.Error(), res.Error.Message)
|
| 5650 |
+
}
|
| 5651 |
+
})
|
| 5652 |
+
}
|
| 5653 |
+
}
|
|
@@ -204,6 +204,53 @@
|
|
| 204 |
})
|
| 205 |
}
|
| 206 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 207 |
// GetFullBlockByNumber returns information about a block by block number
|
| 208 |
func (z *ZKEVMEndpoints) GetFullBlockByNumber(number types.BlockNumber, fullTx bool) (interface{}, types.Error) {
|
| 209 |
return z.txMan.NewDbTxScope(z.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) {
|
|
@@ -516,7 +563,7 @@
|
|
| 516 |
|
| 517 |
if txEGP.Cmp(txGasPrice) == -1 { // txEGP < txGasPrice
|
| 518 |
// We need to "round" the final effectiveGasPrice to a 256 fraction of the txGasPrice
|
| 519 |
-
txEGPPct, err =
|
| 520 |
if err != nil {
|
| 521 |
return nil, nil, types.NewRPCError(types.DefaultErrorCode, "failed to calculate effective gas price percentage", err, false)
|
| 522 |
}
|
|
|
|
| 204 |
})
|
| 205 |
}
|
| 206 |
|
| 207 |
+
type batchDataFunc func(ctx context.Context, batchNumbers []uint64, dbTx pgx.Tx) (map[uint64][]byte, error)
|
| 208 |
+
|
| 209 |
+
// GetBatchDataByNumbers returns L2 batch data by batch numbers.
|
| 210 |
+
func (z *ZKEVMEndpoints) GetBatchDataByNumbers(filter types.BatchFilter) (interface{}, types.Error) {
|
| 211 |
+
return z.getBatchData(filter, z.state.GetBatchL2DataByNumbers)
|
| 212 |
+
}
|
| 213 |
+
|
| 214 |
+
// GetForcedBatchDataByNumbers returns forced batch data by batch numbers.
|
| 215 |
+
func (z *ZKEVMEndpoints) GetForcedBatchDataByNumbers(filter types.BatchFilter) (interface{}, types.Error) {
|
| 216 |
+
return z.getBatchData(filter, z.state.GetForcedBatchDataByNumbers)
|
| 217 |
+
}
|
| 218 |
+
|
| 219 |
+
func (z *ZKEVMEndpoints) getBatchData(filter types.BatchFilter, f batchDataFunc) (interface{}, types.Error) {
|
| 220 |
+
return z.txMan.NewDbTxScope(z.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) {
|
| 221 |
+
batchNumbers := make([]uint64, 0, len(filter.Numbers))
|
| 222 |
+
for _, bn := range filter.Numbers {
|
| 223 |
+
n, rpcErr := bn.GetNumericBatchNumber(ctx, z.state, z.etherman, dbTx)
|
| 224 |
+
if rpcErr != nil {
|
| 225 |
+
return nil, rpcErr
|
| 226 |
+
}
|
| 227 |
+
batchNumbers = append(batchNumbers, n)
|
| 228 |
+
}
|
| 229 |
+
|
| 230 |
+
batchesData, err := f(ctx, batchNumbers, dbTx)
|
| 231 |
+
if errors.Is(err, state.ErrNotFound) {
|
| 232 |
+
return nil, nil
|
| 233 |
+
} else if err != nil {
|
| 234 |
+
return RPCErrorResponse(types.DefaultErrorCode,
|
| 235 |
+
fmt.Sprintf("couldn't load batch data from state by numbers %v", filter.Numbers), err, true)
|
| 236 |
+
}
|
| 237 |
+
|
| 238 |
+
ret := make([]*types.BatchData, 0, len(batchNumbers))
|
| 239 |
+
for _, n := range batchNumbers {
|
| 240 |
+
data := &types.BatchData{Number: types.ArgUint64(n)}
|
| 241 |
+
if b, ok := batchesData[n]; ok {
|
| 242 |
+
data.BatchL2Data = b
|
| 243 |
+
data.Empty = false
|
| 244 |
+
} else {
|
| 245 |
+
data.Empty = true
|
| 246 |
+
}
|
| 247 |
+
ret = append(ret, data)
|
| 248 |
+
}
|
| 249 |
+
|
| 250 |
+
return types.BatchDataResult{Data: ret}, nil
|
| 251 |
+
})
|
| 252 |
+
}
|
| 253 |
+
|
| 254 |
// GetFullBlockByNumber returns information about a block by block number
|
| 255 |
func (z *ZKEVMEndpoints) GetFullBlockByNumber(number types.BlockNumber, fullTx bool) (interface{}, types.Error) {
|
| 256 |
return z.txMan.NewDbTxScope(z.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) {
|
|
|
|
| 563 |
|
| 564 |
if txEGP.Cmp(txGasPrice) == -1 { // txEGP < txGasPrice
|
| 565 |
// We need to "round" the final effectiveGasPrice to a 256 fraction of the txGasPrice
|
| 566 |
+
txEGPPct, err = state.CalculateEffectiveGasPricePercentage(txGasPrice, txEGP)
|
| 567 |
if err != nil {
|
| 568 |
return nil, nil, types.NewRPCError(types.DefaultErrorCode, "failed to calculate effective gas price percentage", err, false)
|
| 569 |
}
|
|
@@ -2705,3 +2705,32 @@
|
|
| 2705 |
})
|
| 2706 |
}
|
| 2707 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2705 |
})
|
| 2706 |
}
|
| 2707 |
}
|
| 2708 |
+
|
| 2709 |
+
func TestClient_BatchesByNumbers(t *testing.T) {
|
| 2710 |
+
const batchesCount = 6
|
| 2711 |
+
|
| 2712 |
+
s, m, _ := newSequencerMockedServer(t)
|
| 2713 |
+
defer s.Stop()
|
| 2714 |
+
|
| 2715 |
+
batchesDataMap := make(map[uint64][]byte, batchesCount)
|
| 2716 |
+
for i := 0; i < batchesCount; i++ {
|
| 2717 |
+
batchesDataMap[uint64(i+1)] = []byte(fmt.Sprintf("batch %d data", i+1))
|
| 2718 |
+
}
|
| 2719 |
+
|
| 2720 |
+
m.State.On("GetBatchL2DataByNumbers", mock.Anything, mock.Anything, mock.Anything).
|
| 2721 |
+
Return(batchesDataMap, nil).Once()
|
| 2722 |
+
|
| 2723 |
+
m.State.On("BeginStateTransaction", context.Background()).
|
| 2724 |
+
Return(m.DbTx, nil).Once()
|
| 2725 |
+
|
| 2726 |
+
m.DbTx.On("Commit", context.Background()).Return(nil).Once()
|
| 2727 |
+
|
| 2728 |
+
zkEVMClient := client.NewClient(s.ServerURL)
|
| 2729 |
+
reqBatchesNum := []*big.Int{big.NewInt(1), big.NewInt(3), big.NewInt(4)}
|
| 2730 |
+
result, err := zkEVMClient.BatchesByNumbers(context.Background(), reqBatchesNum)
|
| 2731 |
+
require.NoError(t, err)
|
| 2732 |
+
require.Len(t, result, len(reqBatchesNum))
|
| 2733 |
+
for i, batchNum := range reqBatchesNum {
|
| 2734 |
+
require.Equal(t, hex.EncodeToHex(batchesDataMap[batchNum.Uint64()]), result[i].BatchL2Data.Hex())
|
| 2735 |
+
}
|
| 2736 |
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package jsonrpc
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"context"
|
| 5 |
+
|
| 6 |
+
"github.com/0xPolygonHermez/zkevm-node/jsonrpc/types"
|
| 7 |
+
"github.com/0xPolygonHermez/zkevm-node/pool"
|
| 8 |
+
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 9 |
+
"github.com/ethereum/go-ethereum/common"
|
| 10 |
+
ethTypes "github.com/ethereum/go-ethereum/core/types"
|
| 11 |
+
)
|
| 12 |
+
|
| 13 |
+
func checkPolicy(ctx context.Context, p types.PoolInterface, input string) error {
|
| 14 |
+
tx, err := hexToTx(input)
|
| 15 |
+
if err != nil {
|
| 16 |
+
// ignore it, let the later processing reject
|
| 17 |
+
return nil
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
// if the tx is signed, check the from address. If there is no from address, the tx is not rejected as it
|
| 21 |
+
// will get rejected later. This maintains backward compatibility with RPC expectations. TODO: verify this is ok behavior
|
| 22 |
+
var from common.Address
|
| 23 |
+
if from, err = state.GetSender(*tx); err != nil {
|
| 24 |
+
// if not signed, then skip check, it fails later on its own
|
| 25 |
+
return nil
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
switch resolvePolicy(tx) {
|
| 29 |
+
case pool.SendTx:
|
| 30 |
+
var allow bool
|
| 31 |
+
if allow, err = p.CheckPolicy(ctx, pool.SendTx, *tx.To()); err != nil {
|
| 32 |
+
return err
|
| 33 |
+
}
|
| 34 |
+
if !allow {
|
| 35 |
+
return pool.ErrContractDisallowedSendTx
|
| 36 |
+
}
|
| 37 |
+
if allow, err = p.CheckPolicy(ctx, pool.SendTx, from); err != nil {
|
| 38 |
+
return err
|
| 39 |
+
}
|
| 40 |
+
if !allow {
|
| 41 |
+
return pool.ErrSenderDisallowedSendTx
|
| 42 |
+
}
|
| 43 |
+
case pool.Deploy:
|
| 44 |
+
var allow bool
|
| 45 |
+
// check that sender may deploy contracts
|
| 46 |
+
if allow, err = p.CheckPolicy(ctx, pool.Deploy, from); err != nil {
|
| 47 |
+
return err
|
| 48 |
+
}
|
| 49 |
+
if !allow {
|
| 50 |
+
return pool.ErrSenderDisallowedDeploy
|
| 51 |
+
}
|
| 52 |
+
}
|
| 53 |
+
return nil
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
func resolvePolicy(tx *ethTypes.Transaction) pool.PolicyName {
|
| 57 |
+
if tx.To() == nil || tx.To().Hex() == common.HexToAddress("0x0").Hex() {
|
| 58 |
+
return pool.Deploy
|
| 59 |
+
}
|
| 60 |
+
return pool.SendTx
|
| 61 |
+
}
|
|
@@ -15,6 +15,8 @@
|
|
| 15 |
InvalidParamsErrorCode = -32602
|
| 16 |
// ParserErrorCode error code for parsing errors
|
| 17 |
ParserErrorCode = -32700
|
|
|
|
|
|
|
| 18 |
)
|
| 19 |
|
| 20 |
var (
|
|
|
|
| 15 |
InvalidParamsErrorCode = -32602
|
| 16 |
// ParserErrorCode error code for parsing errors
|
| 17 |
ParserErrorCode = -32700
|
| 18 |
+
// AccessDeniedCode error code when requests are denied
|
| 19 |
+
AccessDeniedCode = -32800
|
| 20 |
)
|
| 21 |
|
| 22 |
var (
|
|
@@ -23,8 +23,8 @@
|
|
| 23 |
CountPendingTransactions(ctx context.Context) (uint64, error)
|
| 24 |
GetTransactionByHash(ctx context.Context, hash common.Hash) (*pool.Transaction, error)
|
| 25 |
GetTransactionByL2Hash(ctx context.Context, hash common.Hash) (*pool.Transaction, error)
|
|
|
|
| 26 |
CalculateEffectiveGasPrice(rawTx []byte, txGasPrice *big.Int, txGasUsed uint64, l1GasPrice uint64, l2GasPrice uint64) (*big.Int, error)
|
| 27 |
-
CalculateEffectiveGasPricePercentage(gasPrice *big.Int, effectiveGasPrice *big.Int) (uint8, error)
|
| 28 |
EffectiveGasPriceEnabled() bool
|
| 29 |
}
|
| 30 |
|
|
@@ -64,6 +64,8 @@
|
|
| 64 |
GetLastVerifiedBatch(ctx context.Context, dbTx pgx.Tx) (*state.VerifiedBatch, error)
|
| 65 |
GetLastBatchNumber(ctx context.Context, dbTx pgx.Tx) (uint64, error)
|
| 66 |
GetBatchByNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.Batch, error)
|
|
|
|
|
|
|
| 67 |
GetTransactionsByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (txs []types.Transaction, effectivePercentages []uint8, err error)
|
| 68 |
GetVirtualBatch(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.VirtualBatch, error)
|
| 69 |
GetVerifiedBatch(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.VerifiedBatch, error)
|
|
|
|
| 23 |
CountPendingTransactions(ctx context.Context) (uint64, error)
|
| 24 |
GetTransactionByHash(ctx context.Context, hash common.Hash) (*pool.Transaction, error)
|
| 25 |
GetTransactionByL2Hash(ctx context.Context, hash common.Hash) (*pool.Transaction, error)
|
| 26 |
+
CheckPolicy(ctx context.Context, policy pool.PolicyName, address common.Address) (bool, error)
|
| 27 |
CalculateEffectiveGasPrice(rawTx []byte, txGasPrice *big.Int, txGasUsed uint64, l1GasPrice uint64, l2GasPrice uint64) (*big.Int, error)
|
|
|
|
| 28 |
EffectiveGasPriceEnabled() bool
|
| 29 |
}
|
| 30 |
|
|
|
|
| 64 |
GetLastVerifiedBatch(ctx context.Context, dbTx pgx.Tx) (*state.VerifiedBatch, error)
|
| 65 |
GetLastBatchNumber(ctx context.Context, dbTx pgx.Tx) (uint64, error)
|
| 66 |
GetBatchByNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.Batch, error)
|
| 67 |
+
GetBatchL2DataByNumbers(ctx context.Context, batchNumbers []uint64, dbTx pgx.Tx) (map[uint64][]byte, error)
|
| 68 |
+
GetForcedBatchDataByNumbers(ctx context.Context, batchNumbers []uint64, dbTx pgx.Tx) (map[uint64][]byte, error)
|
| 69 |
GetTransactionsByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (txs []types.Transaction, effectivePercentages []uint8, err error)
|
| 70 |
GetVirtualBatch(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.VirtualBatch, error)
|
| 71 |
GetVerifiedBatch(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.VerifiedBatch, error)
|
|
@@ -446,6 +446,23 @@
|
|
| 446 |
return res, nil
|
| 447 |
}
|
| 448 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 449 |
// TransactionOrHash for union type of transaction and types.Hash
|
| 450 |
type TransactionOrHash struct {
|
| 451 |
Hash *common.Hash
|
|
|
|
| 446 |
return res, nil
|
| 447 |
}
|
| 448 |
|
| 449 |
+
// BatchFilter is a list of batch numbers to retrieve
|
| 450 |
+
type BatchFilter struct {
|
| 451 |
+
Numbers []BatchNumber `json:"numbers"`
|
| 452 |
+
}
|
| 453 |
+
|
| 454 |
+
// BatchData is an abbreviated structure that only contains the number and L2 batch data
|
| 455 |
+
type BatchData struct {
|
| 456 |
+
Number ArgUint64 `json:"number"`
|
| 457 |
+
BatchL2Data ArgBytes `json:"batchL2Data,omitempty"`
|
| 458 |
+
Empty bool `json:"empty"`
|
| 459 |
+
}
|
| 460 |
+
|
| 461 |
+
// BatchDataResult is a list of BatchData for a BatchFilter
|
| 462 |
+
type BatchDataResult struct {
|
| 463 |
+
Data []*BatchData `json:"data"`
|
| 464 |
+
}
|
| 465 |
+
|
| 466 |
// TransactionOrHash for union type of transaction and types.Hash
|
| 467 |
type TransactionOrHash struct {
|
| 468 |
Hash *common.Hash
|
|
@@ -26,7 +26,7 @@
|
|
| 26 |
var err error
|
| 27 |
mt.siblings, mt.currentRoot, err = mt.initSiblings(initialLeaves)
|
| 28 |
if err != nil {
|
| 29 |
-
log.Error("error initializing
|
| 30 |
return nil, err
|
| 31 |
}
|
| 32 |
log.Debug("Initial count: ", mt.count)
|
|
@@ -34,6 +34,25 @@
|
|
| 34 |
return mt, nil
|
| 35 |
}
|
| 36 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
func buildIntermediate(leaves [][32]byte) ([][][]byte, [][32]byte) {
|
| 38 |
var (
|
| 39 |
nodes [][][]byte
|
|
|
|
| 26 |
var err error
|
| 27 |
mt.siblings, mt.currentRoot, err = mt.initSiblings(initialLeaves)
|
| 28 |
if err != nil {
|
| 29 |
+
log.Error("error initializing siblings. Error: ", err)
|
| 30 |
return nil, err
|
| 31 |
}
|
| 32 |
log.Debug("Initial count: ", mt.count)
|
|
|
|
| 34 |
return mt, nil
|
| 35 |
}
|
| 36 |
|
| 37 |
+
// ResetL1InfoTree resets the L1InfoTree.
|
| 38 |
+
func (mt *L1InfoTree) ResetL1InfoTree(initialLeaves [][32]byte) (*L1InfoTree, error) {
|
| 39 |
+
log.Info("Resetting L1InfoTree...")
|
| 40 |
+
newMT := &L1InfoTree{
|
| 41 |
+
zeroHashes: generateZeroHashes(32), // nolint:gomnd
|
| 42 |
+
height: 32, // nolint:gomnd
|
| 43 |
+
count: uint32(len(initialLeaves)),
|
| 44 |
+
}
|
| 45 |
+
var err error
|
| 46 |
+
newMT.siblings, newMT.currentRoot, err = newMT.initSiblings(initialLeaves)
|
| 47 |
+
if err != nil {
|
| 48 |
+
log.Error("error initializing siblings. Error: ", err)
|
| 49 |
+
return nil, err
|
| 50 |
+
}
|
| 51 |
+
log.Debug("Reset initial count: ", newMT.count)
|
| 52 |
+
log.Debug("Reset initial root: ", newMT.currentRoot)
|
| 53 |
+
return newMT, nil
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
func buildIntermediate(leaves [][32]byte) ([][][]byte, [][32]byte) {
|
| 57 |
var (
|
| 58 |
nodes [][][]byte
|
|
@@ -2,21 +2,12 @@
|
|
| 2 |
|
| 3 |
import (
|
| 4 |
"bytes"
|
| 5 |
-
"errors"
|
| 6 |
"math/big"
|
| 7 |
|
| 8 |
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 9 |
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 10 |
)
|
| 11 |
|
| 12 |
-
var (
|
| 13 |
-
// ErrEffectiveGasPriceEmpty happens when the effectiveGasPrice or gasPrice is nil or zero
|
| 14 |
-
ErrEffectiveGasPriceEmpty = errors.New("effectiveGasPrice or gasPrice cannot be nil or zero")
|
| 15 |
-
|
| 16 |
-
// ErrEffectiveGasPriceIsZero happens when the calculated EffectiveGasPrice is zero
|
| 17 |
-
ErrEffectiveGasPriceIsZero = errors.New("effectiveGasPrice cannot be zero")
|
| 18 |
-
)
|
| 19 |
-
|
| 20 |
// EffectiveGasPrice implements the effective gas prices calculations and checks
|
| 21 |
type EffectiveGasPrice struct {
|
| 22 |
cfg EffectiveGasPriceCfg
|
|
@@ -122,33 +113,8 @@
|
|
| 122 |
bfEffectiveGasPrice.Int(effectiveGasPrice)
|
| 123 |
|
| 124 |
if effectiveGasPrice.Cmp(new(big.Int).SetUint64(0)) == 0 {
|
| 125 |
-
return nil, ErrEffectiveGasPriceIsZero
|
| 126 |
}
|
| 127 |
|
| 128 |
return effectiveGasPrice, nil
|
| 129 |
}
|
| 130 |
-
|
| 131 |
-
// CalculateEffectiveGasPricePercentage calculates the gas price's effective percentage
|
| 132 |
-
func (e *EffectiveGasPrice) CalculateEffectiveGasPricePercentage(gasPrice *big.Int, effectiveGasPrice *big.Int) (uint8, error) {
|
| 133 |
-
const bits = 256
|
| 134 |
-
var bitsBigInt = big.NewInt(bits)
|
| 135 |
-
|
| 136 |
-
if effectiveGasPrice == nil || gasPrice == nil ||
|
| 137 |
-
gasPrice.Cmp(big.NewInt(0)) == 0 || effectiveGasPrice.Cmp(big.NewInt(0)) == 0 {
|
| 138 |
-
return 0, ErrEffectiveGasPriceEmpty
|
| 139 |
-
}
|
| 140 |
-
|
| 141 |
-
if gasPrice.Cmp(effectiveGasPrice) <= 0 {
|
| 142 |
-
return state.MaxEffectivePercentage, nil
|
| 143 |
-
}
|
| 144 |
-
|
| 145 |
-
// Simulate Ceil with integer division
|
| 146 |
-
b := new(big.Int).Mul(effectiveGasPrice, bitsBigInt)
|
| 147 |
-
b = b.Add(b, gasPrice)
|
| 148 |
-
b = b.Sub(b, big.NewInt(1)) //nolint:gomnd
|
| 149 |
-
b = b.Div(b, gasPrice)
|
| 150 |
-
// At this point we have a percentage between 1-256, we need to sub 1 to have it between 0-255 (byte)
|
| 151 |
-
b = b.Sub(b, big.NewInt(1)) //nolint:gomnd
|
| 152 |
-
|
| 153 |
-
return uint8(b.Uint64()), nil
|
| 154 |
-
}
|
|
|
|
| 2 |
|
| 3 |
import (
|
| 4 |
"bytes"
|
|
|
|
| 5 |
"math/big"
|
| 6 |
|
| 7 |
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 8 |
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 9 |
)
|
| 10 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
// EffectiveGasPrice implements the effective gas prices calculations and checks
|
| 12 |
type EffectiveGasPrice struct {
|
| 13 |
cfg EffectiveGasPriceCfg
|
|
|
|
| 113 |
bfEffectiveGasPrice.Int(effectiveGasPrice)
|
| 114 |
|
| 115 |
if effectiveGasPrice.Cmp(new(big.Int).SetUint64(0)) == 0 {
|
| 116 |
+
return nil, state.ErrEffectiveGasPriceIsZero
|
| 117 |
}
|
| 118 |
|
| 119 |
return effectiveGasPrice, nil
|
| 120 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -23,8 +24,6 @@
|
|
| 23 |
)
|
| 24 |
|
| 25 |
func TestCalculateEffectiveGasPricePercentage(t *testing.T) {
|
| 26 |
-
egp := NewEffectiveGasPrice(egpCfg)
|
| 27 |
-
|
| 28 |
testCases := []struct {
|
| 29 |
name string
|
| 30 |
breakEven *big.Int
|
|
@@ -37,14 +36,14 @@
|
|
| 37 |
name: "Nil breakEven or gasPrice",
|
| 38 |
gasPrice: big.NewInt(1),
|
| 39 |
expectedValue: uint8(0),
|
| 40 |
-
err: ErrEffectiveGasPriceEmpty,
|
| 41 |
},
|
| 42 |
{
|
| 43 |
name: "Zero breakEven or gasPrice",
|
| 44 |
breakEven: big.NewInt(1),
|
| 45 |
gasPrice: big.NewInt(0),
|
| 46 |
expectedValue: uint8(0),
|
| 47 |
-
err: ErrEffectiveGasPriceEmpty,
|
| 48 |
},
|
| 49 |
{
|
| 50 |
name: "Both positive, gasPrice less than breakEven",
|
|
@@ -104,7 +103,7 @@
|
|
| 104 |
|
| 105 |
for _, tc := range testCases {
|
| 106 |
t.Run(tc.name, func(t *testing.T) {
|
| 107 |
-
actual, err :=
|
| 108 |
assert.Equal(t, tc.err, err)
|
| 109 |
if actual != 0 {
|
| 110 |
assert.Equal(t, tc.expectedValue, actual)
|
|
|
|
| 24 |
)
|
| 25 |
|
| 26 |
func TestCalculateEffectiveGasPricePercentage(t *testing.T) {
|
|
|
|
|
|
|
| 27 |
testCases := []struct {
|
| 28 |
name string
|
| 29 |
breakEven *big.Int
|
|
|
|
| 36 |
name: "Nil breakEven or gasPrice",
|
| 37 |
gasPrice: big.NewInt(1),
|
| 38 |
expectedValue: uint8(0),
|
| 39 |
+
err: state.ErrEffectiveGasPriceEmpty,
|
| 40 |
},
|
| 41 |
{
|
| 42 |
name: "Zero breakEven or gasPrice",
|
| 43 |
breakEven: big.NewInt(1),
|
| 44 |
gasPrice: big.NewInt(0),
|
| 45 |
expectedValue: uint8(0),
|
| 46 |
+
err: state.ErrEffectiveGasPriceEmpty,
|
| 47 |
},
|
| 48 |
{
|
| 49 |
name: "Both positive, gasPrice less than breakEven",
|
|
|
|
| 103 |
|
| 104 |
for _, tc := range testCases {
|
| 105 |
t.Run(tc.name, func(t *testing.T) {
|
| 106 |
+
actual, err := state.CalculateEffectiveGasPricePercentage(tc.gasPrice, tc.breakEven)
|
| 107 |
assert.Equal(t, tc.err, err)
|
| 108 |
if actual != 0 {
|
| 109 |
assert.Equal(t, tc.expectedValue, actual)
|
|
@@ -76,4 +76,13 @@
|
|
| 76 |
|
| 77 |
// ErrZeroL1GasPrice is returned if the L1 gas price is 0.
|
| 78 |
ErrZeroL1GasPrice = errors.New("L1 gas price 0")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 79 |
)
|
|
|
|
| 76 |
|
| 77 |
// ErrZeroL1GasPrice is returned if the L1 gas price is 0.
|
| 78 |
ErrZeroL1GasPrice = errors.New("L1 gas price 0")
|
| 79 |
+
|
| 80 |
+
// ErrSenderDisallowedSendTx is returned when transactions by sender are is disallowed by policy
|
| 81 |
+
ErrSenderDisallowedSendTx = errors.New("sender disallowed send_tx by policy")
|
| 82 |
+
|
| 83 |
+
// ErrContractDisallowedSendTx is returned when transactions to contract are is disallowed by policy
|
| 84 |
+
ErrContractDisallowedSendTx = errors.New("contract disallowed send_tx by policy")
|
| 85 |
+
|
| 86 |
+
// ErrSenderDisallowedDeploy is returned when deploy transactions are disallowed by policy
|
| 87 |
+
ErrSenderDisallowedDeploy = errors.New("sender disallowed deploy by policy")
|
| 88 |
)
|
|
@@ -38,6 +38,7 @@
|
|
| 38 |
MarkWIPTxsAsPending(ctx context.Context) error
|
| 39 |
GetAllAddressesBlocked(ctx context.Context) ([]common.Address, error)
|
| 40 |
MinL2GasPriceSince(ctx context.Context, timestamp time.Time) (uint64, error)
|
|
|
|
| 41 |
GetEarliestProcessedTx(ctx context.Context) (common.Hash, error)
|
| 42 |
}
|
| 43 |
|
|
@@ -48,3 +49,12 @@
|
|
| 48 |
GetTransactionByHash(ctx context.Context, transactionHash common.Hash, dbTx pgx.Tx) (*types.Transaction, error)
|
| 49 |
PreProcessTransaction(ctx context.Context, tx *types.Transaction, dbTx pgx.Tx) (*state.ProcessBatchResponse, error)
|
| 50 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
MarkWIPTxsAsPending(ctx context.Context) error
|
| 39 |
GetAllAddressesBlocked(ctx context.Context) ([]common.Address, error)
|
| 40 |
MinL2GasPriceSince(ctx context.Context, timestamp time.Time) (uint64, error)
|
| 41 |
+
policy
|
| 42 |
GetEarliestProcessedTx(ctx context.Context) (common.Hash, error)
|
| 43 |
}
|
| 44 |
|
|
|
|
| 49 |
GetTransactionByHash(ctx context.Context, transactionHash common.Hash, dbTx pgx.Tx) (*types.Transaction, error)
|
| 50 |
PreProcessTransaction(ctx context.Context, tx *types.Transaction, dbTx pgx.Tx) (*state.ProcessBatchResponse, error)
|
| 51 |
}
|
| 52 |
+
type policy interface {
|
| 53 |
+
CheckPolicy(ctx context.Context, policy PolicyName, address common.Address) (bool, error)
|
| 54 |
+
AddAddressesToPolicy(ctx context.Context, policy PolicyName, addresses []common.Address) error
|
| 55 |
+
RemoveAddressesFromPolicy(ctx context.Context, policy PolicyName, addresses []common.Address) error
|
| 56 |
+
ClearPolicy(ctx context.Context, policy PolicyName) error
|
| 57 |
+
DescribePolicies(ctx context.Context) ([]Policy, error)
|
| 58 |
+
DescribePolicy(ctx context.Context, name PolicyName) (Policy, error)
|
| 59 |
+
ListAcl(ctx context.Context, policy PolicyName, query []common.Address) ([]common.Address, error)
|
| 60 |
+
}
|
|
@@ -0,0 +1,202 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package pgpoolstorage
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"context"
|
| 5 |
+
"errors"
|
| 6 |
+
"fmt"
|
| 7 |
+
"strings"
|
| 8 |
+
|
| 9 |
+
"github.com/0xPolygonHermez/zkevm-node/pool"
|
| 10 |
+
"github.com/ethereum/go-ethereum/common"
|
| 11 |
+
"github.com/jackc/pgx/v4"
|
| 12 |
+
)
|
| 13 |
+
|
| 14 |
+
// CheckPolicy returns the rule for the named policy and address. If the address is associated with the policy, the rule
|
| 15 |
+
// will be the setting for the policy. If the address is no associated with the policy, the rule will be the opposite of
|
| 16 |
+
// the policy setting.
|
| 17 |
+
func (p *PostgresPoolStorage) CheckPolicy(ctx context.Context, policy pool.PolicyName, address common.Address) (bool, error) {
|
| 18 |
+
sql := `SELECT
|
| 19 |
+
CASE WHEN a.address is null THEN
|
| 20 |
+
NOT p.allow
|
| 21 |
+
ELSE
|
| 22 |
+
p.allow
|
| 23 |
+
END
|
| 24 |
+
FROM pool.policy p
|
| 25 |
+
LEFT JOIN pool.acl a
|
| 26 |
+
ON p.name = a.policy
|
| 27 |
+
AND a.address = $1
|
| 28 |
+
WHERE p.name = $2`
|
| 29 |
+
|
| 30 |
+
rows, err := p.db.Query(ctx, sql, address.Hex(), policy)
|
| 31 |
+
|
| 32 |
+
if errors.Is(err, pgx.ErrNoRows) {
|
| 33 |
+
return false, pool.ErrNotFound
|
| 34 |
+
} else if err != nil {
|
| 35 |
+
return false, err
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
defer rows.Close()
|
| 39 |
+
if !rows.Next() { // should always be a row if the policy exists
|
| 40 |
+
return false, nil
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
var allow bool
|
| 44 |
+
err = rows.Scan(&allow)
|
| 45 |
+
if err != nil {
|
| 46 |
+
return false, err
|
| 47 |
+
}
|
| 48 |
+
return allow, nil
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
// UpdatePolicy sets the allow/deny rule for the named policy
|
| 52 |
+
func (p *PostgresPoolStorage) UpdatePolicy(ctx context.Context, policy pool.PolicyName, allow bool) error {
|
| 53 |
+
sql := "UPDATE pool.policy SET allow = $1 WHERE name = $2"
|
| 54 |
+
_, err := p.db.Exec(ctx, sql, allow, string(policy))
|
| 55 |
+
if err != nil {
|
| 56 |
+
return err
|
| 57 |
+
}
|
| 58 |
+
return nil
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
// AddAddressesToPolicy adds addresses to the named policy
|
| 62 |
+
func (p *PostgresPoolStorage) AddAddressesToPolicy(ctx context.Context, policy pool.PolicyName, addresses []common.Address) error {
|
| 63 |
+
sql := "INSERT INTO pool.acl (policy, address) VALUES ($1, $2) ON CONFLICT DO NOTHING"
|
| 64 |
+
tx, err := p.db.Begin(ctx)
|
| 65 |
+
if err != nil {
|
| 66 |
+
return err
|
| 67 |
+
}
|
| 68 |
+
defer func(tx pgx.Tx, ctx context.Context) {
|
| 69 |
+
_ = tx.Rollback(ctx)
|
| 70 |
+
}(tx, ctx)
|
| 71 |
+
|
| 72 |
+
for _, a := range addresses {
|
| 73 |
+
_, err = tx.Exec(ctx, sql, policy, a.Hex())
|
| 74 |
+
if err != nil {
|
| 75 |
+
return err
|
| 76 |
+
}
|
| 77 |
+
}
|
| 78 |
+
err = tx.Commit(ctx)
|
| 79 |
+
if err != nil {
|
| 80 |
+
return nil
|
| 81 |
+
}
|
| 82 |
+
return nil
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
// RemoveAddressesFromPolicy removes addresses from the named policy
|
| 86 |
+
func (p *PostgresPoolStorage) RemoveAddressesFromPolicy(ctx context.Context, policy pool.PolicyName, addresses []common.Address) error {
|
| 87 |
+
sql := "DELETE FROM pool.acl WHERE policy = $1 AND address = $2"
|
| 88 |
+
tx, err := p.db.Begin(ctx)
|
| 89 |
+
if err != nil {
|
| 90 |
+
return err
|
| 91 |
+
}
|
| 92 |
+
defer func(tx pgx.Tx, ctx context.Context) {
|
| 93 |
+
_ = tx.Rollback(ctx)
|
| 94 |
+
}(tx, ctx)
|
| 95 |
+
|
| 96 |
+
for _, a := range addresses {
|
| 97 |
+
_, err = tx.Exec(ctx, sql, policy, a.Hex())
|
| 98 |
+
if err != nil {
|
| 99 |
+
return err
|
| 100 |
+
}
|
| 101 |
+
}
|
| 102 |
+
err = tx.Commit(ctx)
|
| 103 |
+
if err != nil {
|
| 104 |
+
return err
|
| 105 |
+
}
|
| 106 |
+
return nil
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
// ClearPolicy removes _all_ addresses from the named policy
|
| 110 |
+
func (p *PostgresPoolStorage) ClearPolicy(ctx context.Context, policy pool.PolicyName) error {
|
| 111 |
+
sql := "DELETE FROM pool.acl WHERE policy = $1"
|
| 112 |
+
_, err := p.db.Exec(ctx, sql, policy)
|
| 113 |
+
if err != nil {
|
| 114 |
+
return err
|
| 115 |
+
}
|
| 116 |
+
return nil
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
// DescribePolicies return all the policies
|
| 120 |
+
func (p *PostgresPoolStorage) DescribePolicies(ctx context.Context) ([]pool.Policy, error) {
|
| 121 |
+
sql := "SELECT name, allow FROM pool.policy"
|
| 122 |
+
rows, err := p.db.Query(ctx, sql)
|
| 123 |
+
if err != nil {
|
| 124 |
+
if errors.Is(err, pgx.ErrNoRows) {
|
| 125 |
+
return nil, nil
|
| 126 |
+
} else {
|
| 127 |
+
return nil, err
|
| 128 |
+
}
|
| 129 |
+
}
|
| 130 |
+
defer rows.Close()
|
| 131 |
+
|
| 132 |
+
var list []pool.Policy
|
| 133 |
+
for rows.Next() {
|
| 134 |
+
var name string
|
| 135 |
+
var allow bool
|
| 136 |
+
err = rows.Scan(&name, &allow)
|
| 137 |
+
if err != nil {
|
| 138 |
+
return nil, err
|
| 139 |
+
}
|
| 140 |
+
if pool.IsPolicy(name) { // skip unknown
|
| 141 |
+
p := pool.Policy{
|
| 142 |
+
Name: pool.PolicyName(name),
|
| 143 |
+
Allow: allow,
|
| 144 |
+
}
|
| 145 |
+
list = append(list, p)
|
| 146 |
+
}
|
| 147 |
+
}
|
| 148 |
+
return list, nil
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
+
// DescribePolicy returns the named policy
|
| 152 |
+
func (p *PostgresPoolStorage) DescribePolicy(ctx context.Context, name pool.PolicyName) (pool.Policy, error) {
|
| 153 |
+
sql := "SELECT name, allow FROM pool.policy WHERE name = $1 LIMIT 1"
|
| 154 |
+
row := p.db.QueryRow(ctx, sql, name)
|
| 155 |
+
var (
|
| 156 |
+
pName string
|
| 157 |
+
allow bool
|
| 158 |
+
)
|
| 159 |
+
err := row.Scan(&pName, &allow)
|
| 160 |
+
if err != nil {
|
| 161 |
+
return pool.Policy{}, err
|
| 162 |
+
}
|
| 163 |
+
return pool.Policy{
|
| 164 |
+
Name: pool.PolicyName(pName),
|
| 165 |
+
Allow: allow,
|
| 166 |
+
}, nil
|
| 167 |
+
}
|
| 168 |
+
|
| 169 |
+
// ListAcl returns a list of the addresses associated with the policy
|
| 170 |
+
func (p *PostgresPoolStorage) ListAcl(
|
| 171 |
+
ctx context.Context, policy pool.PolicyName, query []common.Address) ([]common.Address, error) {
|
| 172 |
+
sql := "SELECT address FROM pool.acl WHERE policy = $1"
|
| 173 |
+
|
| 174 |
+
if len(query) > 0 {
|
| 175 |
+
var addrs []string
|
| 176 |
+
for _, a := range query {
|
| 177 |
+
addrs = append(addrs, a.Hex())
|
| 178 |
+
}
|
| 179 |
+
sql = sql + fmt.Sprintf(" IN (%v)", strings.Join(addrs, ","))
|
| 180 |
+
}
|
| 181 |
+
|
| 182 |
+
rows, err := p.db.Query(ctx, sql, string(policy))
|
| 183 |
+
if err != nil {
|
| 184 |
+
if errors.Is(err, pgx.ErrNoRows) {
|
| 185 |
+
return nil, nil
|
| 186 |
+
} else {
|
| 187 |
+
return nil, err
|
| 188 |
+
}
|
| 189 |
+
}
|
| 190 |
+
defer rows.Close()
|
| 191 |
+
|
| 192 |
+
var addresses []common.Address
|
| 193 |
+
for rows.Next() {
|
| 194 |
+
var addr string
|
| 195 |
+
err = rows.Scan(&addr)
|
| 196 |
+
if err != nil {
|
| 197 |
+
return nil, err
|
| 198 |
+
}
|
| 199 |
+
addresses = append(addresses, common.HexToAddress(addr))
|
| 200 |
+
}
|
| 201 |
+
return addresses, nil
|
| 202 |
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package pool
|
| 2 |
+
|
| 3 |
+
import "github.com/ethereum/go-ethereum/common"
|
| 4 |
+
|
| 5 |
+
// PolicyName is a named policy
|
| 6 |
+
type PolicyName string
|
| 7 |
+
|
| 8 |
+
const (
|
| 9 |
+
// SendTx is the name of the policy that governs that an address may send transactions to pool
|
| 10 |
+
SendTx PolicyName = "send_tx"
|
| 11 |
+
// Deploy is the name of the policy that governs that an address may deploy a contract
|
| 12 |
+
Deploy PolicyName = "deploy"
|
| 13 |
+
)
|
| 14 |
+
|
| 15 |
+
// Policy describes state of a named policy
|
| 16 |
+
type Policy struct {
|
| 17 |
+
Name PolicyName
|
| 18 |
+
Allow bool
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
// Desc returns the string representation of a policy rule
|
| 22 |
+
func (p *Policy) Desc() string {
|
| 23 |
+
if p.Allow {
|
| 24 |
+
return "allow"
|
| 25 |
+
}
|
| 26 |
+
return "deny"
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
// Acl describes exception to a named Policy by address
|
| 30 |
+
type Acl struct {
|
| 31 |
+
PolicyName PolicyName
|
| 32 |
+
Address common.Address
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
// IsPolicy tests if a string represents a known named Policy
|
| 36 |
+
func IsPolicy(name string) bool {
|
| 37 |
+
for _, p := range []PolicyName{SendTx, Deploy} {
|
| 38 |
+
if name == string(p) {
|
| 39 |
+
return true
|
| 40 |
+
}
|
| 41 |
+
}
|
| 42 |
+
return false
|
| 43 |
+
}
|
|
@@ -93,6 +93,13 @@
|
|
| 93 |
time.Sleep(cfg.IntervalToRefreshGasPrices.Duration)
|
| 94 |
}
|
| 95 |
}(&cfg, p)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
|
| 97 |
return p
|
| 98 |
}
|
|
@@ -686,7 +693,7 @@
|
|
| 686 |
|
| 687 |
// CalculateEffectiveGasPricePercentage calculates the gas price's effective percentage
|
| 688 |
func (p *Pool) CalculateEffectiveGasPricePercentage(gasPrice *big.Int, effectiveGasPrice *big.Int) (uint8, error) {
|
| 689 |
-
return
|
| 690 |
}
|
| 691 |
|
| 692 |
// EffectiveGasPriceEnabled returns if effective gas price calculation is enabled or not
|
|
@@ -728,3 +735,8 @@
|
|
| 728 |
}
|
| 729 |
return gas, nil
|
| 730 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 93 |
time.Sleep(cfg.IntervalToRefreshGasPrices.Duration)
|
| 94 |
}
|
| 95 |
}(&cfg, p)
|
| 96 |
+
p.refreshBlockedAddresses()
|
| 97 |
+
go func(cfg *Config, p *Pool) {
|
| 98 |
+
for {
|
| 99 |
+
time.Sleep(cfg.IntervalToRefreshBlockedAddresses.Duration)
|
| 100 |
+
p.refreshBlockedAddresses()
|
| 101 |
+
}
|
| 102 |
+
}(&cfg, p)
|
| 103 |
|
| 104 |
return p
|
| 105 |
}
|
|
|
|
| 693 |
|
| 694 |
// CalculateEffectiveGasPricePercentage calculates the gas price's effective percentage
|
| 695 |
func (p *Pool) CalculateEffectiveGasPricePercentage(gasPrice *big.Int, effectiveGasPrice *big.Int) (uint8, error) {
|
| 696 |
+
return state.CalculateEffectiveGasPricePercentage(gasPrice, effectiveGasPrice)
|
| 697 |
}
|
| 698 |
|
| 699 |
// EffectiveGasPriceEnabled returns if effective gas price calculation is enabled or not
|
|
|
|
| 735 |
}
|
| 736 |
return gas, nil
|
| 737 |
}
|
| 738 |
+
|
| 739 |
+
// CheckPolicy checks if an address is allowed by policy name
|
| 740 |
+
func (p *Pool) CheckPolicy(ctx context.Context, policy PolicyName, address common.Address) (bool, error) {
|
| 741 |
+
return p.storage.CheckPolicy(ctx, policy, address)
|
| 742 |
+
}
|
|
@@ -2032,3 +2032,69 @@
|
|
| 2032 |
require.NoError(t, err)
|
| 2033 |
return signedTx
|
| 2034 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2032 |
require.NoError(t, err)
|
| 2033 |
return signedTx
|
| 2034 |
}
|
| 2035 |
+
|
| 2036 |
+
func Test_PolicyAcl(t *testing.T) {
|
| 2037 |
+
initOrResetDB(t)
|
| 2038 |
+
|
| 2039 |
+
poolSqlDB, err := db.NewSQLDB(poolDBCfg)
|
| 2040 |
+
require.NoError(t, err)
|
| 2041 |
+
defer poolSqlDB.Close() //nolint:gosec,errcheck
|
| 2042 |
+
|
| 2043 |
+
ctx := context.Background()
|
| 2044 |
+
s, err := pgpoolstorage.NewPostgresPoolStorage(poolDBCfg)
|
| 2045 |
+
require.NoError(t, err)
|
| 2046 |
+
|
| 2047 |
+
p := pool.NewPool(cfg, bc, s, nil, uint64(1), nil)
|
| 2048 |
+
|
| 2049 |
+
randAddr := func() common.Address {
|
| 2050 |
+
buf := make([]byte, 20)
|
| 2051 |
+
_, err = rand.Read(buf)
|
| 2052 |
+
require.NoError(t, err)
|
| 2053 |
+
return common.BytesToAddress(buf)
|
| 2054 |
+
}
|
| 2055 |
+
|
| 2056 |
+
// Policies start out as deny lists, since there are no addresses on the
|
| 2057 |
+
// lists, random addresses will always be allowed
|
| 2058 |
+
for _, policy := range []pool.PolicyName{pool.SendTx, pool.Deploy} {
|
| 2059 |
+
allow, err := p.CheckPolicy(ctx, policy, randAddr())
|
| 2060 |
+
require.NoError(t, err)
|
| 2061 |
+
require.True(t, allow)
|
| 2062 |
+
}
|
| 2063 |
+
|
| 2064 |
+
addr := randAddr()
|
| 2065 |
+
|
| 2066 |
+
// put addr on lists
|
| 2067 |
+
for _, policy := range []pool.PolicyName{pool.SendTx, pool.Deploy} {
|
| 2068 |
+
ctag, err := poolSqlDB.Exec(ctx, "INSERT INTO pool.acl (policy, address) VALUES ($1,$2)", policy, addr.Hex())
|
| 2069 |
+
require.NoError(t, err)
|
| 2070 |
+
require.Equal(t, int64(1), ctag.RowsAffected())
|
| 2071 |
+
}
|
| 2072 |
+
|
| 2073 |
+
// addr should not be denied by policy
|
| 2074 |
+
for _, policy := range []pool.PolicyName{pool.SendTx, pool.Deploy} {
|
| 2075 |
+
allow, err := p.CheckPolicy(ctx, policy, addr)
|
| 2076 |
+
require.NoError(t, err)
|
| 2077 |
+
require.False(t, allow)
|
| 2078 |
+
}
|
| 2079 |
+
|
| 2080 |
+
// change policies to allow by acl
|
| 2081 |
+
ctag, err := poolSqlDB.Exec(ctx, "UPDATE pool.policy SET allow = true")
|
| 2082 |
+
require.NoError(t, err)
|
| 2083 |
+
require.Equal(t, int64(2), ctag.RowsAffected())
|
| 2084 |
+
|
| 2085 |
+
// addr is now allowed
|
| 2086 |
+
for _, policy := range []pool.PolicyName{pool.SendTx, pool.Deploy} {
|
| 2087 |
+
allow, err := p.CheckPolicy(ctx, policy, addr)
|
| 2088 |
+
require.NoError(t, err)
|
| 2089 |
+
require.True(t, allow)
|
| 2090 |
+
}
|
| 2091 |
+
|
| 2092 |
+
// random addrs are now denied
|
| 2093 |
+
for _, policy := range []pool.PolicyName{pool.SendTx, pool.Deploy} {
|
| 2094 |
+
for _, a := range []common.Address{randAddr(), randAddr()} {
|
| 2095 |
+
allow, err := s.CheckPolicy(ctx, policy, a)
|
| 2096 |
+
require.NoError(t, err)
|
| 2097 |
+
require.False(t, allow)
|
| 2098 |
+
}
|
| 2099 |
+
}
|
| 2100 |
+
}
|
|
@@ -292,6 +292,7 @@
|
|
| 292 |
// prior to executing the call.
|
| 293 |
map<string, OverrideAccountV2> state_override = 23;
|
| 294 |
DebugV2 debug = 24;
|
|
|
|
| 295 |
}
|
| 296 |
|
| 297 |
message L1DataV2 {
|
|
|
|
| 292 |
// prior to executing the call.
|
| 293 |
map<string, OverrideAccountV2> state_override = 23;
|
| 294 |
DebugV2 debug = 24;
|
| 295 |
+
uint64 execution_mode = 25;
|
| 296 |
}
|
| 297 |
|
| 298 |
message L1DataV2 {
|
|
@@ -211,6 +211,10 @@
|
|
| 211 |
if oldReadyTx != nil && oldReadyTx.Nonce > a.currentNonce {
|
| 212 |
log.Infof("set readyTx %s as notReadyTx from addrQueue %s", oldReadyTx.HashStr, a.fromStr)
|
| 213 |
a.notReadyTxs[oldReadyTx.Nonce] = oldReadyTx
|
|
|
|
|
|
|
|
|
|
|
|
|
| 214 |
}
|
| 215 |
|
| 216 |
return a.readyTx, oldReadyTx, txsToDelete
|
|
|
|
| 211 |
if oldReadyTx != nil && oldReadyTx.Nonce > a.currentNonce {
|
| 212 |
log.Infof("set readyTx %s as notReadyTx from addrQueue %s", oldReadyTx.HashStr, a.fromStr)
|
| 213 |
a.notReadyTxs[oldReadyTx.Nonce] = oldReadyTx
|
| 214 |
+
} else if oldReadyTx != nil { // if oldReadyTx doesn't have a valid nonce then we add it to the txsToDelete
|
| 215 |
+
reason := runtime.ErrIntrinsicInvalidNonce.Error()
|
| 216 |
+
oldReadyTx.FailedReason = &reason
|
| 217 |
+
txsToDelete = append(txsToDelete, oldReadyTx)
|
| 218 |
}
|
| 219 |
|
| 220 |
return a.readyTx, oldReadyTx, txsToDelete
|
|
@@ -42,6 +43,7 @@
|
|
| 42 |
l2Transactions = append(l2Transactions, l2Transaction)
|
| 43 |
}
|
| 44 |
|
|
|
|
| 45 |
f.dataToStream <- state.DSL2FullBlock{
|
| 46 |
DSL2Block: l2Block,
|
| 47 |
Txs: l2Transactions,
|
|
|
|
| 43 |
l2Transactions = append(l2Transactions, l2Transaction)
|
| 44 |
}
|
| 45 |
|
| 46 |
+
log.Infof("sending l2block %d to datastream channel", blockResponse.BlockNumber)
|
| 47 |
f.dataToStream <- state.DSL2FullBlock{
|
| 48 |
DSL2Block: l2Block,
|
| 49 |
Txs: l2Transactions,
|
|
@@ -38,7 +39,7 @@
|
|
| 38 |
workerIntf workerInterface
|
| 39 |
poolIntf txPool
|
| 40 |
stateIntf stateInterface
|
| 41 |
-
etherman
|
| 42 |
wipBatch *Batch
|
| 43 |
wipL2Block *L2Block
|
| 44 |
batchConstraints state.BatchConstraintsCfg
|
|
@@ -87,7 +88,7 @@
|
|
| 87 |
workerIntf workerInterface,
|
| 88 |
poolIntf txPool,
|
| 89 |
stateIntf stateInterface,
|
| 90 |
-
etherman
|
| 91 |
sequencerAddr common.Address,
|
| 92 |
isSynced func(ctx context.Context) bool,
|
| 93 |
batchConstraints state.BatchConstraintsCfg,
|
|
@@ -220,10 +221,98 @@
|
|
| 220 |
f.storedFlushIDCond.L.Unlock()
|
| 221 |
}
|
| 222 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 223 |
func (f *finalizer) checkL1InfoTreeUpdate(ctx context.Context) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 224 |
firstL1InfoRootUpdate := true
|
| 225 |
skipFirstSleep := true
|
| 226 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 227 |
for {
|
| 228 |
if skipFirstSleep {
|
| 229 |
skipFirstSleep = false
|
|
@@ -244,7 +333,7 @@
|
|
| 244 |
|
| 245 |
l1InfoRoot, err := f.stateIntf.GetLatestL1InfoRoot(ctx, maxBlockNumber)
|
| 246 |
if err != nil {
|
| 247 |
-
log.Errorf("error
|
| 248 |
continue
|
| 249 |
}
|
| 250 |
|
|
@@ -254,26 +343,19 @@
|
|
| 254 |
}
|
| 255 |
|
| 256 |
if firstL1InfoRootUpdate || l1InfoRoot.L1InfoTreeIndex > f.lastL1InfoTree.L1InfoTreeIndex {
|
| 257 |
-
log.Infof("received new
|
| 258 |
-
l1InfoRoot.L1InfoTreeIndex, l1InfoRoot.L1InfoTreeRoot, l1InfoRoot.BlockNumber)
|
| 259 |
|
| 260 |
-
//
|
| 261 |
-
if l1InfoRoot.
|
| 262 |
-
|
| 263 |
if err != nil {
|
| 264 |
-
log.Errorf("error
|
| 265 |
continue
|
| 266 |
}
|
| 267 |
|
| 268 |
-
|
| 269 |
-
|
| 270 |
-
|
| 271 |
-
continue
|
| 272 |
-
}
|
| 273 |
-
if l1BlockState.BlockHash != l1BlockEth.Hash() {
|
| 274 |
-
log.Warnf("skipping use of l1InfoTreeIndex %d, L1 block %d blockhash %s doesn't match blockhash on ethereum %s (L1 reorg?)",
|
| 275 |
-
l1InfoRoot.L1InfoTreeIndex, l1InfoRoot.BlockNumber, l1BlockState.BlockHash, l1BlockEth.Hash())
|
| 276 |
-
continue
|
| 277 |
}
|
| 278 |
}
|
| 279 |
|
|
@@ -283,12 +365,7 @@
|
|
| 283 |
f.lastL1InfoTree = l1InfoRoot
|
| 284 |
f.lastL1InfoTreeMux.Unlock()
|
| 285 |
|
| 286 |
-
|
| 287 |
-
f.lastL1InfoTreeCond.L.Lock()
|
| 288 |
-
f.lastL1InfoTreeValid = true
|
| 289 |
-
f.lastL1InfoTreeCond.Broadcast()
|
| 290 |
-
f.lastL1InfoTreeCond.L.Unlock()
|
| 291 |
-
}
|
| 292 |
}
|
| 293 |
}
|
| 294 |
}
|
|
@@ -390,6 +467,7 @@
|
|
| 390 |
SkipWriteBlockInfoRoot_V2: true,
|
| 391 |
SkipVerifyL1InfoRoot_V2: true,
|
| 392 |
L1InfoTreeData_V2: map[uint32]state.L1DataV2{},
|
|
|
|
| 393 |
}
|
| 394 |
|
| 395 |
txGasPrice := tx.GasPrice
|
|
@@ -436,7 +514,7 @@
|
|
| 436 |
}
|
| 437 |
}
|
| 438 |
|
| 439 |
-
egpPercentage, err :=
|
| 440 |
if err != nil {
|
| 441 |
if f.effectiveGasPrice.IsEnabled() {
|
| 442 |
return nil, err
|
|
@@ -549,7 +627,7 @@
|
|
| 549 |
|
| 550 |
// If EffectiveGasPrice is disabled we will calculate the percentage and save it for later logging
|
| 551 |
if !egpEnabled {
|
| 552 |
-
effectivePercentage, err :=
|
| 553 |
if err != nil {
|
| 554 |
log.Warnf("effectiveGasPrice is disabled, but failed to calculate effective gas price percentage (#2), error: %v", err)
|
| 555 |
tx.EGPLog.Error = fmt.Sprintf("%s, CalculateEffectiveGasPricePercentage#2: %s", tx.EGPLog.Error, err)
|
|
|
|
| 39 |
workerIntf workerInterface
|
| 40 |
poolIntf txPool
|
| 41 |
stateIntf stateInterface
|
| 42 |
+
etherman ethermanInterface
|
| 43 |
wipBatch *Batch
|
| 44 |
wipL2Block *L2Block
|
| 45 |
batchConstraints state.BatchConstraintsCfg
|
|
|
|
| 88 |
workerIntf workerInterface,
|
| 89 |
poolIntf txPool,
|
| 90 |
stateIntf stateInterface,
|
| 91 |
+
etherman ethermanInterface,
|
| 92 |
sequencerAddr common.Address,
|
| 93 |
isSynced func(ctx context.Context) bool,
|
| 94 |
batchConstraints state.BatchConstraintsCfg,
|
|
|
|
| 221 |
f.storedFlushIDCond.L.Unlock()
|
| 222 |
}
|
| 223 |
|
| 224 |
+
func (f *finalizer) checkValidL1InfoRoot(ctx context.Context, l1InfoRoot state.L1InfoTreeExitRootStorageEntry) (bool, error) {
|
| 225 |
+
// Check L1 block hash matches
|
| 226 |
+
l1BlockState, err := f.stateIntf.GetBlockByNumber(ctx, l1InfoRoot.BlockNumber, nil)
|
| 227 |
+
if err != nil {
|
| 228 |
+
return false, fmt.Errorf("error getting L1 block %d from the state, error: %v", l1InfoRoot.BlockNumber, err)
|
| 229 |
+
}
|
| 230 |
+
|
| 231 |
+
l1BlockEth, err := f.etherman.HeaderByNumber(ctx, new(big.Int).SetUint64(l1InfoRoot.BlockNumber))
|
| 232 |
+
if err != nil {
|
| 233 |
+
return false, fmt.Errorf("error getting L1 block %d from ethereum, error: %v", l1InfoRoot.BlockNumber, err)
|
| 234 |
+
}
|
| 235 |
+
|
| 236 |
+
if l1BlockState.BlockHash != l1BlockEth.Hash() {
|
| 237 |
+
warnmsg := fmt.Sprintf("invalid l1InfoRoot %s, index: %d, GER: %s, l1Block: %d. L1 block hash %s doesn't match block hash on ethereum %s (L1 reorg?)",
|
| 238 |
+
l1InfoRoot.L1InfoTreeRoot, l1InfoRoot.L1InfoTreeIndex, l1InfoRoot.GlobalExitRoot.GlobalExitRoot, l1InfoRoot.BlockNumber, l1BlockState.BlockHash, l1BlockEth.Hash())
|
| 239 |
+
log.Warnf(warnmsg)
|
| 240 |
+
f.LogEvent(ctx, event.Level_Critical, event.EventID_InvalidInfoRoot, warnmsg, nil)
|
| 241 |
+
|
| 242 |
+
return false, nil
|
| 243 |
+
}
|
| 244 |
+
|
| 245 |
+
// Check l1InfoRootIndex and GER matches. We retrieve the info of the last l1InfoTree event in the block, since in the case we have several l1InfoTree events
|
| 246 |
+
// in the same block, the function checkL1InfoTreeUpdate retrieves only the last one and skips the others
|
| 247 |
+
log.Debugf("getting l1InfoRoot events for L1 block %d, hash: %s", l1InfoRoot.BlockNumber, l1BlockState.BlockHash)
|
| 248 |
+
blocks, eventsOrder, err := f.etherman.GetRollupInfoByBlockRange(ctx, l1InfoRoot.BlockNumber, &l1InfoRoot.BlockNumber)
|
| 249 |
+
if err != nil {
|
| 250 |
+
return false, err
|
| 251 |
+
}
|
| 252 |
+
|
| 253 |
+
//Get L1InfoTree events of the L1 block where the l1InforRoot we need to check was synced
|
| 254 |
+
lastGER := state.ZeroHash
|
| 255 |
+
for _, block := range blocks {
|
| 256 |
+
blockEventsOrder := eventsOrder[block.BlockHash]
|
| 257 |
+
for _, order := range blockEventsOrder {
|
| 258 |
+
if order.Name == ethermanTypes.L1InfoTreeOrder {
|
| 259 |
+
lastGER = block.L1InfoTree[order.Pos].GlobalExitRoot
|
| 260 |
+
log.Debugf("l1InfoTree event, pos: %d, GER: %s", order.Pos, lastGER)
|
| 261 |
+
}
|
| 262 |
+
}
|
| 263 |
+
}
|
| 264 |
+
|
| 265 |
+
// Get the deposit count in the moment when the L1InfoRoot was synced
|
| 266 |
+
depositCount, err := f.etherman.DepositCount(ctx, &l1InfoRoot.BlockNumber)
|
| 267 |
+
if err != nil {
|
| 268 |
+
return false, err
|
| 269 |
+
}
|
| 270 |
+
// l1InfoTree index starts at 0, therefore we need to subtract 1 to the depositCount to get the last index at that moment
|
| 271 |
+
index := uint32(depositCount.Uint64())
|
| 272 |
+
if index > 0 { // we check this as protection, but depositCount should be greater that 0 in this context
|
| 273 |
+
index--
|
| 274 |
+
} else {
|
| 275 |
+
warnmsg := fmt.Sprintf("invalid l1InfoRoot %s, index: %d, GER: %s, blockNum: %d. DepositCount value returned by the smartcontrat is 0 and that isn't possible in this context",
|
| 276 |
+
l1InfoRoot.L1InfoTreeRoot, l1InfoRoot.L1InfoTreeIndex, l1InfoRoot.GlobalExitRoot.GlobalExitRoot, l1InfoRoot.BlockNumber)
|
| 277 |
+
log.Warn(warnmsg)
|
| 278 |
+
f.LogEvent(ctx, event.Level_Critical, event.EventID_InvalidInfoRoot, warnmsg, nil)
|
| 279 |
+
|
| 280 |
+
return false, nil
|
| 281 |
+
}
|
| 282 |
+
|
| 283 |
+
log.Debugf("checking valid l1InfoRoot, index: %d, GER: %s, l1Block: %d, scIndex: %d, scGER: %s",
|
| 284 |
+
l1InfoRoot.BlockNumber, l1InfoRoot.L1InfoTreeIndex, l1InfoRoot.GlobalExitRoot.GlobalExitRoot, index, lastGER)
|
| 285 |
+
|
| 286 |
+
if (l1InfoRoot.GlobalExitRoot.GlobalExitRoot != lastGER) || (l1InfoRoot.L1InfoTreeIndex != index) {
|
| 287 |
+
warnmsg := fmt.Sprintf("invalid l1InfoRoot %s, index: %d, GER: %s, blockNum: %d. It doesn't match with smartcontract l1InfoRoot, index: %d, GER: %s",
|
| 288 |
+
l1InfoRoot.L1InfoTreeRoot, l1InfoRoot.L1InfoTreeIndex, l1InfoRoot.GlobalExitRoot.GlobalExitRoot, l1InfoRoot.BlockNumber, index, lastGER)
|
| 289 |
+
log.Warn(warnmsg)
|
| 290 |
+
f.LogEvent(ctx, event.Level_Critical, event.EventID_InvalidInfoRoot, warnmsg, nil)
|
| 291 |
+
|
| 292 |
+
return false, nil
|
| 293 |
+
}
|
| 294 |
+
|
| 295 |
+
return true, nil
|
| 296 |
+
}
|
| 297 |
+
|
| 298 |
func (f *finalizer) checkL1InfoTreeUpdate(ctx context.Context) {
|
| 299 |
+
broadcastL1InfoTreeValid := func() {
|
| 300 |
+
if !f.lastL1InfoTreeValid {
|
| 301 |
+
f.lastL1InfoTreeCond.L.Lock()
|
| 302 |
+
f.lastL1InfoTreeValid = true
|
| 303 |
+
f.lastL1InfoTreeCond.Broadcast()
|
| 304 |
+
f.lastL1InfoTreeCond.L.Unlock()
|
| 305 |
+
}
|
| 306 |
+
}
|
| 307 |
+
|
| 308 |
firstL1InfoRootUpdate := true
|
| 309 |
skipFirstSleep := true
|
| 310 |
|
| 311 |
+
if f.cfg.L1InfoTreeCheckInterval.Duration.Seconds() == 0 { //nolint:gomnd
|
| 312 |
+
broadcastL1InfoTreeValid()
|
| 313 |
+
return
|
| 314 |
+
}
|
| 315 |
+
|
| 316 |
for {
|
| 317 |
if skipFirstSleep {
|
| 318 |
skipFirstSleep = false
|
|
|
|
| 333 |
|
| 334 |
l1InfoRoot, err := f.stateIntf.GetLatestL1InfoRoot(ctx, maxBlockNumber)
|
| 335 |
if err != nil {
|
| 336 |
+
log.Errorf("error getting latest l1InfoRoot, error: %v", err)
|
| 337 |
continue
|
| 338 |
}
|
| 339 |
|
|
|
|
| 343 |
}
|
| 344 |
|
| 345 |
if firstL1InfoRootUpdate || l1InfoRoot.L1InfoTreeIndex > f.lastL1InfoTree.L1InfoTreeIndex {
|
| 346 |
+
log.Infof("received new l1InfoRoot %s, index: %d, l1Block: %d", l1InfoRoot.L1InfoTreeRoot, l1InfoRoot.L1InfoTreeIndex, l1InfoRoot.BlockNumber)
|
|
|
|
| 347 |
|
| 348 |
+
// Check if new l1InfoRoot is valid. We skip it if l1InfoTreeIndex is 0 (it's a special case)
|
| 349 |
+
if l1InfoRoot.L1InfoTreeIndex > 0 {
|
| 350 |
+
valid, err := f.checkValidL1InfoRoot(ctx, l1InfoRoot)
|
| 351 |
if err != nil {
|
| 352 |
+
log.Errorf("error validating new l1InfoRoot, index: %d, error: %v", l1InfoRoot.L1InfoTreeIndex, err)
|
| 353 |
continue
|
| 354 |
}
|
| 355 |
|
| 356 |
+
if !valid {
|
| 357 |
+
log.Warnf("invalid l1InfoRoot %s, index: %d, l1Block: %d. Stopping syncing l1InfoTreeIndex", l1InfoRoot.L1InfoTreeRoot, l1InfoRoot.L1InfoTreeIndex, l1InfoRoot.BlockNumber)
|
| 358 |
+
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 359 |
}
|
| 360 |
}
|
| 361 |
|
|
|
|
| 365 |
f.lastL1InfoTree = l1InfoRoot
|
| 366 |
f.lastL1InfoTreeMux.Unlock()
|
| 367 |
|
| 368 |
+
broadcastL1InfoTreeValid()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 369 |
}
|
| 370 |
}
|
| 371 |
}
|
|
|
|
| 467 |
SkipWriteBlockInfoRoot_V2: true,
|
| 468 |
SkipVerifyL1InfoRoot_V2: true,
|
| 469 |
L1InfoTreeData_V2: map[uint32]state.L1DataV2{},
|
| 470 |
+
ExecutionMode: executor.ExecutionMode0,
|
| 471 |
}
|
| 472 |
|
| 473 |
txGasPrice := tx.GasPrice
|
|
|
|
| 514 |
}
|
| 515 |
}
|
| 516 |
|
| 517 |
+
egpPercentage, err := state.CalculateEffectiveGasPricePercentage(txGasPrice, tx.EffectiveGasPrice)
|
| 518 |
if err != nil {
|
| 519 |
if f.effectiveGasPrice.IsEnabled() {
|
| 520 |
return nil, err
|
|
|
|
| 627 |
|
| 628 |
// If EffectiveGasPrice is disabled we will calculate the percentage and save it for later logging
|
| 629 |
if !egpEnabled {
|
| 630 |
+
effectivePercentage, err := state.CalculateEffectiveGasPricePercentage(txGasPrice, tx.EffectiveGasPrice)
|
| 631 |
if err != nil {
|
| 632 |
log.Warnf("effectiveGasPrice is disabled, but failed to calculate effective gas price percentage (#2), error: %v", err)
|
| 633 |
tx.EGPLog.Error = fmt.Sprintf("%s, CalculateEffectiveGasPricePercentage#2: %s", tx.EGPLog.Error, err)
|
|
@@ -30,12 +31,14 @@
|
|
| 30 |
GetEarliestProcessedTx(ctx context.Context) (common.Hash, error)
|
| 31 |
}
|
| 32 |
|
| 33 |
-
//
|
| 34 |
-
type
|
| 35 |
TrustedSequencer() (common.Address, error)
|
| 36 |
GetLatestBatchNumber() (uint64, error)
|
| 37 |
GetLatestBlockNumber(ctx context.Context) (uint64, error)
|
| 38 |
HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error)
|
|
|
|
|
|
|
| 39 |
}
|
| 40 |
|
| 41 |
// stateInterface gathers the methods required to interact with the state.
|
|
|
|
| 31 |
GetEarliestProcessedTx(ctx context.Context) (common.Hash, error)
|
| 32 |
}
|
| 33 |
|
| 34 |
+
// ethermanInterface contains the methods required to interact with ethereum.
|
| 35 |
+
type ethermanInterface interface {
|
| 36 |
TrustedSequencer() (common.Address, error)
|
| 37 |
GetLatestBatchNumber() (uint64, error)
|
| 38 |
GetLatestBlockNumber(ctx context.Context) (uint64, error)
|
| 39 |
HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error)
|
| 40 |
+
GetRollupInfoByBlockRange(ctx context.Context, fromBlock uint64, toBlock *uint64) ([]ethermanTypes.Block, map[common.Hash][]ethermanTypes.Order, error)
|
| 41 |
+
DepositCount(ctx context.Context, blockNumber *uint64) (*big.Int, error)
|
| 42 |
}
|
| 43 |
|
| 44 |
// stateInterface gathers the methods required to interact with the state.
|
|
@@ -283,6 +284,7 @@
|
|
| 283 |
ForkID: f.stateIntf.GetForkIDByBatchNumber(f.wipBatch.batchNumber),
|
| 284 |
SkipVerifyL1InfoRoot_V2: true,
|
| 285 |
L1InfoTreeData_V2: map[uint32]state.L1DataV2{},
|
|
|
|
| 286 |
}
|
| 287 |
batchRequest.L1InfoTreeData_V2[l2Block.l1InfoTreeExitRoot.L1InfoTreeIndex] = state.L1DataV2{
|
| 288 |
GlobalExitRoot: l2Block.l1InfoTreeExitRoot.GlobalExitRoot.GlobalExitRoot,
|
|
@@ -411,6 +413,9 @@
|
|
| 411 |
return err
|
| 412 |
}
|
| 413 |
|
|
|
|
|
|
|
|
|
|
| 414 |
// Update txs status in the pool
|
| 415 |
for _, txResponse := range blockResponse.TransactionResponses {
|
| 416 |
// Change Tx status to selected
|
|
@@ -420,6 +425,9 @@
|
|
| 420 |
}
|
| 421 |
}
|
| 422 |
|
|
|
|
|
|
|
|
|
|
| 423 |
// Send L2 block to data streamer
|
| 424 |
err = f.DSSendL2Block(f.wipBatch.batchNumber, blockResponse, l2Block.getL1InfoTreeIndex())
|
| 425 |
if err != nil {
|
|
@@ -427,6 +435,9 @@
|
|
| 427 |
log.Errorf("error sending L2 block %d [%d] to data streamer, error: %v", blockResponse.BlockNumber, l2Block.trackingNum, err)
|
| 428 |
}
|
| 429 |
|
|
|
|
|
|
|
|
|
|
| 430 |
for _, tx := range l2Block.transactions {
|
| 431 |
// Delete the tx from the pending list in the worker (addrQueue)
|
| 432 |
f.workerIntf.DeletePendingTxToStore(tx.Hash, tx.From)
|
|
@@ -582,6 +593,7 @@
|
|
| 582 |
SkipFirstChangeL2Block_V2: false,
|
| 583 |
Transactions: f.stateIntf.BuildChangeL2Block(f.wipL2Block.deltaTimestamp, f.wipL2Block.getL1InfoTreeIndex()),
|
| 584 |
L1InfoTreeData_V2: map[uint32]state.L1DataV2{},
|
|
|
|
| 585 |
}
|
| 586 |
|
| 587 |
batchRequest.L1InfoTreeData_V2[f.wipL2Block.l1InfoTreeExitRoot.L1InfoTreeIndex] = state.L1DataV2{
|
|
|
|
| 284 |
ForkID: f.stateIntf.GetForkIDByBatchNumber(f.wipBatch.batchNumber),
|
| 285 |
SkipVerifyL1InfoRoot_V2: true,
|
| 286 |
L1InfoTreeData_V2: map[uint32]state.L1DataV2{},
|
| 287 |
+
ExecutionMode: executor.ExecutionMode0,
|
| 288 |
}
|
| 289 |
batchRequest.L1InfoTreeData_V2[l2Block.l1InfoTreeExitRoot.L1InfoTreeIndex] = state.L1DataV2{
|
| 290 |
GlobalExitRoot: l2Block.l1InfoTreeExitRoot.GlobalExitRoot.GlobalExitRoot,
|
|
|
|
| 413 |
return err
|
| 414 |
}
|
| 415 |
|
| 416 |
+
//TODO: remove this log
|
| 417 |
+
log.Infof("l2 block %d [%d] stored in statedb", blockResponse.BlockNumber, l2Block.trackingNum)
|
| 418 |
+
|
| 419 |
// Update txs status in the pool
|
| 420 |
for _, txResponse := range blockResponse.TransactionResponses {
|
| 421 |
// Change Tx status to selected
|
|
|
|
| 425 |
}
|
| 426 |
}
|
| 427 |
|
| 428 |
+
//TODO: remove this log
|
| 429 |
+
log.Infof("l2 block %d [%d] transactions updated as selected in the pooldb", blockResponse.BlockNumber, l2Block.trackingNum)
|
| 430 |
+
|
| 431 |
// Send L2 block to data streamer
|
| 432 |
err = f.DSSendL2Block(f.wipBatch.batchNumber, blockResponse, l2Block.getL1InfoTreeIndex())
|
| 433 |
if err != nil {
|
|
|
|
| 435 |
log.Errorf("error sending L2 block %d [%d] to data streamer, error: %v", blockResponse.BlockNumber, l2Block.trackingNum, err)
|
| 436 |
}
|
| 437 |
|
| 438 |
+
//TODO: remove this log
|
| 439 |
+
log.Infof("l2 block %d [%d] sent to datastream", blockResponse.BlockNumber, l2Block.trackingNum)
|
| 440 |
+
|
| 441 |
for _, tx := range l2Block.transactions {
|
| 442 |
// Delete the tx from the pending list in the worker (addrQueue)
|
| 443 |
f.workerIntf.DeletePendingTxToStore(tx.Hash, tx.From)
|
|
|
|
| 593 |
SkipFirstChangeL2Block_V2: false,
|
| 594 |
Transactions: f.stateIntf.BuildChangeL2Block(f.wipL2Block.deltaTimestamp, f.wipL2Block.getL1InfoTreeIndex()),
|
| 595 |
L1InfoTreeData_V2: map[uint32]state.L1DataV2{},
|
| 596 |
+
ExecutionMode: executor.ExecutionMode0,
|
| 597 |
}
|
| 598 |
|
| 599 |
batchRequest.L1InfoTreeData_V2[f.wipL2Block.l1InfoTreeExitRoot.L1InfoTreeIndex] = state.L1DataV2{
|
|
@@ -27,7 +27,7 @@
|
|
| 27 |
pool txPool
|
| 28 |
stateIntf stateInterface
|
| 29 |
eventLog *event.EventLog
|
| 30 |
-
etherman
|
| 31 |
worker *Worker
|
| 32 |
finalizer *finalizer
|
| 33 |
|
|
@@ -42,7 +42,7 @@
|
|
| 42 |
}
|
| 43 |
|
| 44 |
// New init sequencer
|
| 45 |
-
func New(cfg Config, batchCfg state.BatchConfig, poolCfg pool.Config, txPool txPool, stateIntf stateInterface, etherman
|
| 46 |
addr, err := etherman.TrustedSequencer()
|
| 47 |
if err != nil {
|
| 48 |
return nil, fmt.Errorf("failed to get trusted sequencer address, error: %v", err)
|
|
@@ -256,6 +256,8 @@
|
|
| 256 |
case state.DSL2FullBlock:
|
| 257 |
l2Block := data
|
| 258 |
|
|
|
|
|
|
|
| 259 |
err = s.streamServer.StartAtomicOp()
|
| 260 |
if err != nil {
|
| 261 |
log.Errorf("failed to start atomic op for l2block %d, error: %v ", l2Block.L2BlockNumber, err)
|
|
@@ -267,6 +269,8 @@
|
|
| 267 |
Value: l2Block.L2BlockNumber,
|
| 268 |
}
|
| 269 |
|
|
|
|
|
|
|
| 270 |
_, err = s.streamServer.AddStreamBookmark(bookMark.Encode())
|
| 271 |
if err != nil {
|
| 272 |
log.Errorf("failed to add stream bookmark for l2block %d, error: %v", l2Block.L2BlockNumber, err)
|
|
@@ -281,6 +285,8 @@
|
|
| 281 |
Value: l2Block.L2BlockNumber - 1,
|
| 282 |
}
|
| 283 |
|
|
|
|
|
|
|
| 284 |
previousL2BlockEntry, err := s.streamServer.GetFirstEventAfterBookmark(bookMark.Encode())
|
| 285 |
if err != nil {
|
| 286 |
log.Errorf("failed to get previous l2block %d, error: %v", l2Block.L2BlockNumber-1, err)
|
|
@@ -303,12 +309,16 @@
|
|
| 303 |
ChainID: uint32(chainID),
|
| 304 |
}
|
| 305 |
|
|
|
|
|
|
|
| 306 |
_, err = s.streamServer.AddStreamEntry(state.EntryTypeL2BlockStart, blockStart.Encode())
|
| 307 |
if err != nil {
|
| 308 |
log.Errorf("failed to add stream entry for l2block %d, error: %v", l2Block.L2BlockNumber, err)
|
| 309 |
continue
|
| 310 |
}
|
| 311 |
|
|
|
|
|
|
|
| 312 |
for _, l2Transaction := range l2Block.Txs {
|
| 313 |
_, err = s.streamServer.AddStreamEntry(state.EntryTypeL2Tx, l2Transaction.Encode())
|
| 314 |
if err != nil {
|
|
@@ -323,18 +333,25 @@
|
|
| 323 |
StateRoot: l2Block.StateRoot,
|
| 324 |
}
|
| 325 |
|
|
|
|
|
|
|
| 326 |
_, err = s.streamServer.AddStreamEntry(state.EntryTypeL2BlockEnd, blockEnd.Encode())
|
| 327 |
if err != nil {
|
| 328 |
log.Errorf("failed to add stream entry for l2block %d, error: %v", l2Block.L2BlockNumber, err)
|
| 329 |
continue
|
| 330 |
}
|
| 331 |
|
|
|
|
|
|
|
| 332 |
err = s.streamServer.CommitAtomicOp()
|
| 333 |
if err != nil {
|
| 334 |
log.Errorf("failed to commit atomic op for l2block %d, error: %v ", l2Block.L2BlockNumber, err)
|
| 335 |
continue
|
| 336 |
}
|
| 337 |
|
|
|
|
|
|
|
|
|
|
| 338 |
// Stream a bookmark
|
| 339 |
case state.DSBookMark:
|
| 340 |
bookmark := data
|
|
|
|
| 27 |
pool txPool
|
| 28 |
stateIntf stateInterface
|
| 29 |
eventLog *event.EventLog
|
| 30 |
+
etherman ethermanInterface
|
| 31 |
worker *Worker
|
| 32 |
finalizer *finalizer
|
| 33 |
|
|
|
|
| 42 |
}
|
| 43 |
|
| 44 |
// New init sequencer
|
| 45 |
+
func New(cfg Config, batchCfg state.BatchConfig, poolCfg pool.Config, txPool txPool, stateIntf stateInterface, etherman ethermanInterface, eventLog *event.EventLog) (*Sequencer, error) {
|
| 46 |
addr, err := etherman.TrustedSequencer()
|
| 47 |
if err != nil {
|
| 48 |
return nil, fmt.Errorf("failed to get trusted sequencer address, error: %v", err)
|
|
|
|
| 256 |
case state.DSL2FullBlock:
|
| 257 |
l2Block := data
|
| 258 |
|
| 259 |
+
//TODO: remove this log
|
| 260 |
+
log.Infof("start atomic op for l2block %d", l2Block.L2BlockNumber)
|
| 261 |
err = s.streamServer.StartAtomicOp()
|
| 262 |
if err != nil {
|
| 263 |
log.Errorf("failed to start atomic op for l2block %d, error: %v ", l2Block.L2BlockNumber, err)
|
|
|
|
| 269 |
Value: l2Block.L2BlockNumber,
|
| 270 |
}
|
| 271 |
|
| 272 |
+
//TODO: remove this log
|
| 273 |
+
log.Infof("add stream bookmark for l2block %d", l2Block.L2BlockNumber)
|
| 274 |
_, err = s.streamServer.AddStreamBookmark(bookMark.Encode())
|
| 275 |
if err != nil {
|
| 276 |
log.Errorf("failed to add stream bookmark for l2block %d, error: %v", l2Block.L2BlockNumber, err)
|
|
|
|
| 285 |
Value: l2Block.L2BlockNumber - 1,
|
| 286 |
}
|
| 287 |
|
| 288 |
+
//TODO: remove this log
|
| 289 |
+
log.Infof("get previous l2block %d", l2Block.L2BlockNumber-1)
|
| 290 |
previousL2BlockEntry, err := s.streamServer.GetFirstEventAfterBookmark(bookMark.Encode())
|
| 291 |
if err != nil {
|
| 292 |
log.Errorf("failed to get previous l2block %d, error: %v", l2Block.L2BlockNumber-1, err)
|
|
|
|
| 309 |
ChainID: uint32(chainID),
|
| 310 |
}
|
| 311 |
|
| 312 |
+
//TODO: remove this log
|
| 313 |
+
log.Infof("add l2blockStart stream entry for l2block %d", l2Block.L2BlockNumber)
|
| 314 |
_, err = s.streamServer.AddStreamEntry(state.EntryTypeL2BlockStart, blockStart.Encode())
|
| 315 |
if err != nil {
|
| 316 |
log.Errorf("failed to add stream entry for l2block %d, error: %v", l2Block.L2BlockNumber, err)
|
| 317 |
continue
|
| 318 |
}
|
| 319 |
|
| 320 |
+
//TODO: remove this log
|
| 321 |
+
log.Infof("adding l2tx stream entries for l2block %d", l2Block.L2BlockNumber)
|
| 322 |
for _, l2Transaction := range l2Block.Txs {
|
| 323 |
_, err = s.streamServer.AddStreamEntry(state.EntryTypeL2Tx, l2Transaction.Encode())
|
| 324 |
if err != nil {
|
|
|
|
| 333 |
StateRoot: l2Block.StateRoot,
|
| 334 |
}
|
| 335 |
|
| 336 |
+
//TODO: remove this log
|
| 337 |
+
log.Infof("add l2blockEnd stream entry for l2block %d", l2Block.L2BlockNumber)
|
| 338 |
_, err = s.streamServer.AddStreamEntry(state.EntryTypeL2BlockEnd, blockEnd.Encode())
|
| 339 |
if err != nil {
|
| 340 |
log.Errorf("failed to add stream entry for l2block %d, error: %v", l2Block.L2BlockNumber, err)
|
| 341 |
continue
|
| 342 |
}
|
| 343 |
|
| 344 |
+
//TODO: remove this log
|
| 345 |
+
log.Infof("commit atomic op for l2block %d", l2Block.L2BlockNumber)
|
| 346 |
err = s.streamServer.CommitAtomicOp()
|
| 347 |
if err != nil {
|
| 348 |
log.Errorf("failed to commit atomic op for l2block %d, error: %v ", l2Block.L2BlockNumber, err)
|
| 349 |
continue
|
| 350 |
}
|
| 351 |
|
| 352 |
+
//TODO: remove this log
|
| 353 |
+
log.Infof("l2block %d sent to datastream", l2Block.L2BlockNumber)
|
| 354 |
+
|
| 355 |
// Stream a bookmark
|
| 356 |
case state.DSBookMark:
|
| 357 |
bookmark := data
|
|
@@ -23,6 +23,7 @@
|
|
| 23 |
state stateInterface
|
| 24 |
batchConstraints state.BatchConstraintsCfg
|
| 25 |
readyTxsCond *timeoutCond
|
|
|
|
| 26 |
}
|
| 27 |
|
| 28 |
// NewWorker creates an init a worker
|
|
@@ -60,6 +61,12 @@
|
|
| 60 |
return nil, pool.ErrOutOfCounters
|
| 61 |
}
|
| 62 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 63 |
addr, found := w.pool[tx.FromStr]
|
| 64 |
if !found {
|
| 65 |
// Unlock the worker to let execute other worker functions while creating the new AddrQueue
|
|
@@ -174,6 +181,8 @@
|
|
| 174 |
defer w.workerMutex.Unlock()
|
| 175 |
log.Debugf("move tx %s to notReady (from: %s, actualNonce: %d, actualBalance: %s)", txHash.String(), from.String(), actualNonce, actualBalance.String())
|
| 176 |
|
|
|
|
|
|
|
| 177 |
addrQueue, found := w.pool[from.String()]
|
| 178 |
if found {
|
| 179 |
// Sanity check. The txHash must be the readyTx
|
|
@@ -195,6 +204,8 @@
|
|
| 195 |
w.workerMutex.Lock()
|
| 196 |
defer w.workerMutex.Unlock()
|
| 197 |
|
|
|
|
|
|
|
| 198 |
addrQueue, found := w.pool[addr.String()]
|
| 199 |
if found {
|
| 200 |
deletedReadyTx := addrQueue.deleteTx(txHash)
|
|
@@ -293,6 +304,8 @@
|
|
| 293 |
w.workerMutex.Lock()
|
| 294 |
defer w.workerMutex.Unlock()
|
| 295 |
|
|
|
|
|
|
|
| 296 |
if w.txSortedList.len() == 0 {
|
| 297 |
return nil, ErrTransactionsListEmpty
|
| 298 |
}
|
|
@@ -342,6 +355,7 @@
|
|
| 342 |
|
| 343 |
if foundAt != -1 {
|
| 344 |
log.Debugf("best fitting tx %s found at index %d with gasPrice %d", tx.HashStr, foundAt, tx.GasPrice)
|
|
|
|
| 345 |
return tx, nil
|
| 346 |
} else {
|
| 347 |
return nil, ErrNoFittingTransaction
|
|
@@ -382,3 +396,9 @@
|
|
| 382 |
w.readyTxsCond.L.Unlock()
|
| 383 |
}
|
| 384 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
state stateInterface
|
| 24 |
batchConstraints state.BatchConstraintsCfg
|
| 25 |
readyTxsCond *timeoutCond
|
| 26 |
+
wipTx *TxTracker
|
| 27 |
}
|
| 28 |
|
| 29 |
// NewWorker creates an init a worker
|
|
|
|
| 61 |
return nil, pool.ErrOutOfCounters
|
| 62 |
}
|
| 63 |
|
| 64 |
+
if (w.wipTx != nil) && (w.wipTx.FromStr == tx.FromStr) && (w.wipTx.Nonce == tx.Nonce) {
|
| 65 |
+
log.Infof("adding tx %s (nonce %d) from address %s that matches current processing tx %s (nonce %d), rejecting it as duplicated nonce", tx.Hash, tx.Nonce, tx.From, w.wipTx.Hash, w.wipTx.Nonce)
|
| 66 |
+
w.workerMutex.Unlock()
|
| 67 |
+
return nil, ErrDuplicatedNonce
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
addr, found := w.pool[tx.FromStr]
|
| 71 |
if !found {
|
| 72 |
// Unlock the worker to let execute other worker functions while creating the new AddrQueue
|
|
|
|
| 181 |
defer w.workerMutex.Unlock()
|
| 182 |
log.Debugf("move tx %s to notReady (from: %s, actualNonce: %d, actualBalance: %s)", txHash.String(), from.String(), actualNonce, actualBalance.String())
|
| 183 |
|
| 184 |
+
w.resetWipTx(txHash)
|
| 185 |
+
|
| 186 |
addrQueue, found := w.pool[from.String()]
|
| 187 |
if found {
|
| 188 |
// Sanity check. The txHash must be the readyTx
|
|
|
|
| 204 |
w.workerMutex.Lock()
|
| 205 |
defer w.workerMutex.Unlock()
|
| 206 |
|
| 207 |
+
w.resetWipTx(txHash)
|
| 208 |
+
|
| 209 |
addrQueue, found := w.pool[addr.String()]
|
| 210 |
if found {
|
| 211 |
deletedReadyTx := addrQueue.deleteTx(txHash)
|
|
|
|
| 304 |
w.workerMutex.Lock()
|
| 305 |
defer w.workerMutex.Unlock()
|
| 306 |
|
| 307 |
+
w.wipTx = nil
|
| 308 |
+
|
| 309 |
if w.txSortedList.len() == 0 {
|
| 310 |
return nil, ErrTransactionsListEmpty
|
| 311 |
}
|
|
|
|
| 355 |
|
| 356 |
if foundAt != -1 {
|
| 357 |
log.Debugf("best fitting tx %s found at index %d with gasPrice %d", tx.HashStr, foundAt, tx.GasPrice)
|
| 358 |
+
w.wipTx = tx
|
| 359 |
return tx, nil
|
| 360 |
} else {
|
| 361 |
return nil, ErrNoFittingTransaction
|
|
|
|
| 396 |
w.readyTxsCond.L.Unlock()
|
| 397 |
}
|
| 398 |
}
|
| 399 |
+
|
| 400 |
+
func (w *Worker) resetWipTx(txHash common.Hash) {
|
| 401 |
+
if (w.wipTx != nil) && (w.wipTx.Hash == txHash) {
|
| 402 |
+
w.wipTx = nil
|
| 403 |
+
}
|
| 404 |
+
}
|
|
@@ -41,4 +41,6 @@
|
|
| 41 |
// gas offset: 100
|
| 42 |
// final gas: 1100
|
| 43 |
GasOffset uint64 `mapstructure:"GasOffset"`
|
|
|
|
|
|
|
| 44 |
}
|
|
|
|
| 41 |
// gas offset: 100
|
| 42 |
// final gas: 1100
|
| 43 |
GasOffset uint64 `mapstructure:"GasOffset"`
|
| 44 |
+
// MaxBatchesForL1 is the maximum amount of batches to be sequenced in a single L1 tx
|
| 45 |
+
MaxBatchesForL1 uint64 `mapstructure:"MaxBatchesForL1"`
|
| 46 |
}
|
|
@@ -17,8 +17,8 @@
|
|
| 17 |
|
| 18 |
// etherman contains the methods required to interact with ethereum.
|
| 19 |
type etherman interface {
|
| 20 |
-
BuildSequenceBatchesTxData(sender common.Address, sequences []ethmanTypes.Sequence, maxSequenceTimestamp uint64, initSequenceBatchNumber uint64, l2Coinbase common.Address) (to *common.Address, data []byte, err error)
|
| 21 |
-
EstimateGasSequenceBatches(sender common.Address, sequences []ethmanTypes.Sequence, maxSequenceTimestamp uint64, initSequenceBatchNumber uint64, l2Coinbase common.Address) (*types.Transaction, error)
|
| 22 |
GetLatestBlockHeader(ctx context.Context) (*types.Header, error)
|
| 23 |
GetLatestBatchNumber() (uint64, error)
|
| 24 |
}
|
|
@@ -41,3 +41,7 @@
|
|
| 41 |
Add(ctx context.Context, owner, id string, from common.Address, to *common.Address, value *big.Int, data []byte, gasOffset uint64, dbTx pgx.Tx) error
|
| 42 |
ProcessPendingMonitoredTxs(ctx context.Context, owner string, failedResultHandler ethtxmanager.ResultHandler, dbTx pgx.Tx)
|
| 43 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
|
| 18 |
// etherman contains the methods required to interact with ethereum.
|
| 19 |
type etherman interface {
|
| 20 |
+
BuildSequenceBatchesTxData(sender common.Address, sequences []ethmanTypes.Sequence, maxSequenceTimestamp uint64, initSequenceBatchNumber uint64, l2Coinbase common.Address, committeeSignaturesAndAddrs []byte) (to *common.Address, data []byte, err error)
|
| 21 |
+
EstimateGasSequenceBatches(sender common.Address, sequences []ethmanTypes.Sequence, maxSequenceTimestamp uint64, initSequenceBatchNumber uint64, l2Coinbase common.Address, committeeSignaturesAndAddrs []byte) (*types.Transaction, error)
|
| 22 |
GetLatestBlockHeader(ctx context.Context) (*types.Header, error)
|
| 23 |
GetLatestBatchNumber() (uint64, error)
|
| 24 |
}
|
|
|
|
| 41 |
Add(ctx context.Context, owner, id string, from common.Address, to *common.Address, value *big.Int, data []byte, gasOffset uint64, dbTx pgx.Tx) error
|
| 42 |
ProcessPendingMonitoredTxs(ctx context.Context, owner string, failedResultHandler ethtxmanager.ResultHandler, dbTx pgx.Tx)
|
| 43 |
}
|
| 44 |
+
|
| 45 |
+
type dataAbilitier interface {
|
| 46 |
+
PostSequence(ctx context.Context, sequences []ethmanTypes.Sequence) ([]byte, error)
|
| 47 |
+
}
|
|
@@ -6,13 +6,11 @@
|
|
| 6 |
"fmt"
|
| 7 |
"time"
|
| 8 |
|
| 9 |
-
ethman "github.com/0xPolygonHermez/zkevm-node/etherman"
|
| 10 |
"github.com/0xPolygonHermez/zkevm-node/etherman/types"
|
| 11 |
"github.com/0xPolygonHermez/zkevm-node/ethtxmanager"
|
| 12 |
"github.com/0xPolygonHermez/zkevm-node/event"
|
| 13 |
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 14 |
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 15 |
-
ethTypes "github.com/ethereum/go-ethereum/core/types"
|
| 16 |
"github.com/jackc/pgx/v4"
|
| 17 |
)
|
| 18 |
|
|
@@ -41,16 +39,18 @@
|
|
| 41 |
ethTxManager ethTxManager
|
| 42 |
etherman etherman
|
| 43 |
eventLog *event.EventLog
|
|
|
|
| 44 |
}
|
| 45 |
|
| 46 |
// New inits sequence sender
|
| 47 |
-
func New(cfg Config, state stateInterface, etherman etherman, manager ethTxManager, eventLog *event.EventLog) (*SequenceSender, error) {
|
| 48 |
return &SequenceSender{
|
| 49 |
cfg: cfg,
|
| 50 |
state: state,
|
| 51 |
etherman: etherman,
|
| 52 |
ethTxManager: manager,
|
| 53 |
eventLog: eventLog,
|
|
|
|
| 54 |
}, nil
|
| 55 |
}
|
| 56 |
|
|
@@ -185,9 +185,14 @@
|
|
| 185 |
}
|
| 186 |
|
| 187 |
// add sequence to be monitored
|
| 188 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 189 |
|
| 190 |
-
|
|
|
|
| 191 |
if err != nil {
|
| 192 |
log.Error("error estimating new sequenceBatches to add to eth tx manager: ", err)
|
| 193 |
return
|
|
@@ -218,8 +223,6 @@
|
|
| 218 |
sequences := []types.Sequence{}
|
| 219 |
// var estimatedGas uint64
|
| 220 |
|
| 221 |
-
var tx *ethTypes.Transaction
|
| 222 |
-
|
| 223 |
// Add sequences until too big for a single L1 tx or last batch is reached
|
| 224 |
for {
|
| 225 |
//Check if the next batch belongs to a new forkid, in this case we need to stop sequencing as we need to
|
|
@@ -288,31 +291,11 @@
|
|
| 288 |
|
| 289 |
sequences = append(sequences, seq)
|
| 290 |
// Check if can be send
|
| 291 |
-
|
| 292 |
-
|
| 293 |
-
|
| 294 |
-
|
| 295 |
-
|
| 296 |
-
err = ErrOversizedData
|
| 297 |
-
}
|
| 298 |
-
if err != nil {
|
| 299 |
-
log.Infof("Handling estimage gas send sequence error: %v", err)
|
| 300 |
-
sequences, err = s.handleEstimateGasSendSequenceErr(ctx, sequences, currentBatchNumToSequence, err)
|
| 301 |
-
if sequences != nil {
|
| 302 |
-
if len(sequences) > 0 {
|
| 303 |
-
// Handling the error gracefully, re-processing the sequence as a sanity check
|
| 304 |
-
lastSequence = sequences[len(sequences)-1]
|
| 305 |
-
_, err = s.etherman.EstimateGasSequenceBatches(s.cfg.SenderAddress, sequences, uint64(lastSequence.LastL2BLockTimestamp), firstSequence.BatchNumber-1, s.cfg.L2Coinbase)
|
| 306 |
-
return sequences, err
|
| 307 |
-
}
|
| 308 |
-
}
|
| 309 |
-
return sequences, err
|
| 310 |
-
}
|
| 311 |
-
// estimatedGas = tx.Gas()
|
| 312 |
-
|
| 313 |
-
//Check if the current batch is the last before a change to a new forkid, in this case we need to close and send the sequence to L1
|
| 314 |
-
if (s.cfg.ForkUpgradeBatchNumber != 0) && (currentBatchNumToSequence == (s.cfg.ForkUpgradeBatchNumber)) {
|
| 315 |
-
log.Infof("sequence should be sent to L1, as we have reached the batch %d from which a new forkid is applied (upgrade)", s.cfg.ForkUpgradeBatchNumber)
|
| 316 |
return sequences, nil
|
| 317 |
}
|
| 318 |
|
|
@@ -343,78 +326,6 @@
|
|
| 343 |
return nil, nil
|
| 344 |
}
|
| 345 |
|
| 346 |
-
// handleEstimateGasSendSequenceErr handles an error on the estimate gas. It will return:
|
| 347 |
-
// nil, error: impossible to handle gracefully
|
| 348 |
-
// sequence, nil: handled gracefully. Potentially manipulating the sequences
|
| 349 |
-
// nil, nil: a situation that requires waiting
|
| 350 |
-
func (s *SequenceSender) handleEstimateGasSendSequenceErr(
|
| 351 |
-
ctx context.Context,
|
| 352 |
-
sequences []types.Sequence,
|
| 353 |
-
currentBatchNumToSequence uint64,
|
| 354 |
-
err error,
|
| 355 |
-
) ([]types.Sequence, error) {
|
| 356 |
-
// Insufficient allowance
|
| 357 |
-
if errors.Is(err, ethman.ErrInsufficientAllowance) {
|
| 358 |
-
return nil, err
|
| 359 |
-
}
|
| 360 |
-
if isDataForEthTxTooBig(err) {
|
| 361 |
-
// Remove the latest item and send the sequences
|
| 362 |
-
log.Infof(
|
| 363 |
-
"Done building sequences, selected batches to %d. Batch %d caused the L1 tx to be too big",
|
| 364 |
-
currentBatchNumToSequence-1, currentBatchNumToSequence,
|
| 365 |
-
)
|
| 366 |
-
sequences = sequences[:len(sequences)-1]
|
| 367 |
-
return sequences, nil
|
| 368 |
-
}
|
| 369 |
-
|
| 370 |
-
// while estimating gas a new block is not created and the POE SC may return
|
| 371 |
-
// an error regarding timestamp verification, this must be handled
|
| 372 |
-
// if errors.Is(err, ethman.ErrTimestampMustBeInsideRange) {
|
| 373 |
-
// // query the sc about the value of its lastTimestamp variable
|
| 374 |
-
// lastTimestamp, err := s.etherman.GetLastBatchTimestamp()
|
| 375 |
-
// if err != nil {
|
| 376 |
-
// return nil, err
|
| 377 |
-
// }
|
| 378 |
-
// // check POE SC lastTimestamp against sequences' one
|
| 379 |
-
// for _, seq := range sequences {
|
| 380 |
-
// if seq.Timestamp < int64(lastTimestamp) {
|
| 381 |
-
// // TODO: gracefully handle this situation by creating an L2 reorg
|
| 382 |
-
// log.Fatalf("sequence timestamp %d is < POE SC lastTimestamp %d", seq.Timestamp, lastTimestamp)
|
| 383 |
-
// }
|
| 384 |
-
// lastTimestamp = uint64(seq.Timestamp)
|
| 385 |
-
// }
|
| 386 |
-
// blockTimestamp, err := s.etherman.GetLatestBlockTimestamp(ctx)
|
| 387 |
-
// if err != nil {
|
| 388 |
-
// log.Error("error getting block timestamp: ", err)
|
| 389 |
-
// }
|
| 390 |
-
// log.Debugf("block.timestamp: %d is smaller than seq.Timestamp: %d. A new block must be mined in L1 before the gas can be estimated.", blockTimestamp, sequences[0].Timestamp)
|
| 391 |
-
// return nil, nil
|
| 392 |
-
// }
|
| 393 |
-
|
| 394 |
-
// Unknown error
|
| 395 |
-
if len(sequences) == 1 {
|
| 396 |
-
// TODO: gracefully handle this situation by creating an L2 reorg
|
| 397 |
-
log.Errorf(
|
| 398 |
-
"Error when estimating gas for BatchNum %d (alone in the sequences): %v",
|
| 399 |
-
currentBatchNumToSequence, err,
|
| 400 |
-
)
|
| 401 |
-
}
|
| 402 |
-
// Remove the latest item and send the sequences
|
| 403 |
-
log.Infof(
|
| 404 |
-
"Done building sequences, selected batches to %d. Batch %d excluded due to unknown error: %v",
|
| 405 |
-
currentBatchNumToSequence, currentBatchNumToSequence+1, err,
|
| 406 |
-
)
|
| 407 |
-
sequences = sequences[:len(sequences)-1]
|
| 408 |
-
|
| 409 |
-
return sequences, nil
|
| 410 |
-
}
|
| 411 |
-
|
| 412 |
-
func isDataForEthTxTooBig(err error) bool {
|
| 413 |
-
return errors.Is(err, ethman.ErrGasRequiredExceedsAllowance) ||
|
| 414 |
-
errors.Is(err, ErrOversizedData) ||
|
| 415 |
-
errors.Is(err, ethman.ErrContentLengthTooLarge)
|
| 416 |
-
}
|
| 417 |
-
|
| 418 |
func (s *SequenceSender) isSynced(ctx context.Context, retries int, waitRetry time.Duration) (bool, error) {
|
| 419 |
lastVirtualBatchNum, err := s.state.GetLastVirtualBatchNum(ctx, nil)
|
| 420 |
if err != nil && err != state.ErrNotFound {
|
|
|
|
| 6 |
"fmt"
|
| 7 |
"time"
|
| 8 |
|
|
|
|
| 9 |
"github.com/0xPolygonHermez/zkevm-node/etherman/types"
|
| 10 |
"github.com/0xPolygonHermez/zkevm-node/ethtxmanager"
|
| 11 |
"github.com/0xPolygonHermez/zkevm-node/event"
|
| 12 |
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 13 |
"github.com/0xPolygonHermez/zkevm-node/state"
|
|
|
|
| 14 |
"github.com/jackc/pgx/v4"
|
| 15 |
)
|
| 16 |
|
|
|
|
| 39 |
ethTxManager ethTxManager
|
| 40 |
etherman etherman
|
| 41 |
eventLog *event.EventLog
|
| 42 |
+
da dataAbilitier
|
| 43 |
}
|
| 44 |
|
| 45 |
// New inits sequence sender
|
| 46 |
+
func New(cfg Config, state stateInterface, etherman etherman, manager ethTxManager, eventLog *event.EventLog, da dataAbilitier) (*SequenceSender, error) {
|
| 47 |
return &SequenceSender{
|
| 48 |
cfg: cfg,
|
| 49 |
state: state,
|
| 50 |
etherman: etherman,
|
| 51 |
ethTxManager: manager,
|
| 52 |
eventLog: eventLog,
|
| 53 |
+
da: da,
|
| 54 |
}, nil
|
| 55 |
}
|
| 56 |
|
|
|
|
| 185 |
}
|
| 186 |
|
| 187 |
// add sequence to be monitored
|
| 188 |
+
dataAvailabilityMessage, err := s.da.PostSequence(ctx, sequences)
|
| 189 |
+
if err != nil {
|
| 190 |
+
log.Error("error posting sequences to the data availability protocol: ", err)
|
| 191 |
+
return
|
| 192 |
+
}
|
| 193 |
|
| 194 |
+
firstSequence := sequences[0]
|
| 195 |
+
to, data, err := s.etherman.BuildSequenceBatchesTxData(s.cfg.SenderAddress, sequences, uint64(lastSequence.LastL2BLockTimestamp), firstSequence.BatchNumber-1, s.cfg.L2Coinbase, dataAvailabilityMessage)
|
| 196 |
if err != nil {
|
| 197 |
log.Error("error estimating new sequenceBatches to add to eth tx manager: ", err)
|
| 198 |
return
|
|
|
|
| 223 |
sequences := []types.Sequence{}
|
| 224 |
// var estimatedGas uint64
|
| 225 |
|
|
|
|
|
|
|
| 226 |
// Add sequences until too big for a single L1 tx or last batch is reached
|
| 227 |
for {
|
| 228 |
//Check if the next batch belongs to a new forkid, in this case we need to stop sequencing as we need to
|
|
|
|
| 291 |
|
| 292 |
sequences = append(sequences, seq)
|
| 293 |
// Check if can be send
|
| 294 |
+
if len(sequences) == int(s.cfg.MaxBatchesForL1) {
|
| 295 |
+
log.Info(
|
| 296 |
+
"sequence should be sent to L1, because MaxBatchesForL1 (%d) has been reached",
|
| 297 |
+
s.cfg.MaxBatchesForL1,
|
| 298 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 299 |
return sequences, nil
|
| 300 |
}
|
| 301 |
|
|
|
|
| 326 |
return nil, nil
|
| 327 |
}
|
| 328 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 329 |
func (s *SequenceSender) isSynced(ctx context.Context, retries int, waitRetry time.Duration) (bool, error) {
|
| 330 |
lastVirtualBatchNum, err := s.state.GetLastVirtualBatchNum(ctx, nil)
|
| 331 |
if err != nil && err != state.ErrNotFound {
|
|
@@ -30,7 +30,7 @@
|
|
| 30 |
stateMock := new(StateMock)
|
| 31 |
ethermanMock := new(EthermanMock)
|
| 32 |
ethTxManagerMock := new(EthTxManagerMock)
|
| 33 |
-
ssender, err := New(Config{}, stateMock, ethermanMock, ethTxManagerMock, nil)
|
| 34 |
assert.NoError(t, err)
|
| 35 |
|
| 36 |
testCases := []IsSyncedTestCase{
|
|
|
|
| 30 |
stateMock := new(StateMock)
|
| 31 |
ethermanMock := new(EthermanMock)
|
| 32 |
ethTxManagerMock := new(EthTxManagerMock)
|
| 33 |
+
ssender, err := New(Config{}, stateMock, ethermanMock, ethTxManagerMock, nil, nil)
|
| 34 |
assert.NoError(t, err)
|
| 35 |
|
| 36 |
testCases := []IsSyncedTestCase{
|
|
@@ -69,6 +69,7 @@
|
|
| 69 |
ChainId: s.cfg.ChainID,
|
| 70 |
ForkId: request.ForkID,
|
| 71 |
ContextId: uuid.NewString(),
|
|
|
|
| 72 |
}
|
| 73 |
|
| 74 |
if request.SkipFirstChangeL2Block_V2 {
|
|
@@ -131,6 +132,7 @@
|
|
| 131 |
ForkId: forkId,
|
| 132 |
ContextId: uuid.NewString(),
|
| 133 |
SkipVerifyL1InfoRoot: skipVerifyL1InfoRoot,
|
|
|
|
| 134 |
}
|
| 135 |
|
| 136 |
if forcedBlockHashL1 != nil {
|
|
@@ -231,6 +233,7 @@
|
|
| 231 |
ContextId: uuid.NewString(),
|
| 232 |
SkipVerifyL1InfoRoot: processingCtx.SkipVerifyL1InfoRoot,
|
| 233 |
L1InfoRoot: processingCtx.L1InfoRoot.Bytes(),
|
|
|
|
| 234 |
}
|
| 235 |
|
| 236 |
if processingCtx.ForcedBlockHashL1 != nil {
|
|
|
|
| 69 |
ChainId: s.cfg.ChainID,
|
| 70 |
ForkId: request.ForkID,
|
| 71 |
ContextId: uuid.NewString(),
|
| 72 |
+
ExecutionMode: request.ExecutionMode,
|
| 73 |
}
|
| 74 |
|
| 75 |
if request.SkipFirstChangeL2Block_V2 {
|
|
|
|
| 132 |
ForkId: forkId,
|
| 133 |
ContextId: uuid.NewString(),
|
| 134 |
SkipVerifyL1InfoRoot: skipVerifyL1InfoRoot,
|
| 135 |
+
ExecutionMode: executor.ExecutionMode1,
|
| 136 |
}
|
| 137 |
|
| 138 |
if forcedBlockHashL1 != nil {
|
|
|
|
| 233 |
ContextId: uuid.NewString(),
|
| 234 |
SkipVerifyL1InfoRoot: processingCtx.SkipVerifyL1InfoRoot,
|
| 235 |
L1InfoRoot: processingCtx.L1InfoRoot.Bytes(),
|
| 236 |
+
ExecutionMode: processingCtx.ExecutionMode,
|
| 237 |
}
|
| 238 |
|
| 239 |
if processingCtx.ForcedBlockHashL1 != nil {
|
|
@@ -12,6 +12,7 @@
|
|
| 12 |
BlockHash common.Hash
|
| 13 |
ParentHash common.Hash
|
| 14 |
ReceivedAt time.Time
|
|
|
|
| 15 |
}
|
| 16 |
|
| 17 |
// NewBlock creates a block with the given data.
|
|
|
|
| 12 |
BlockHash common.Hash
|
| 13 |
ParentHash common.Hash
|
| 14 |
ReceivedAt time.Time
|
| 15 |
+
Checked bool
|
| 16 |
}
|
| 17 |
|
| 18 |
// NewBlock creates a block with the given data.
|
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package state
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"errors"
|
| 5 |
+
"math/big"
|
| 6 |
+
)
|
| 7 |
+
|
| 8 |
+
const (
|
| 9 |
+
// MaxEffectivePercentage is the maximum value that can be used as effective percentage
|
| 10 |
+
MaxEffectivePercentage = uint8(255)
|
| 11 |
+
)
|
| 12 |
+
|
| 13 |
+
var (
|
| 14 |
+
// ErrEffectiveGasPriceEmpty happens when the effectiveGasPrice or gasPrice is nil or zero
|
| 15 |
+
ErrEffectiveGasPriceEmpty = errors.New("effectiveGasPrice or gasPrice cannot be nil or zero")
|
| 16 |
+
|
| 17 |
+
// ErrEffectiveGasPriceIsZero happens when the calculated EffectiveGasPrice is zero
|
| 18 |
+
ErrEffectiveGasPriceIsZero = errors.New("effectiveGasPrice cannot be zero")
|
| 19 |
+
)
|
| 20 |
+
|
| 21 |
+
// CalculateEffectiveGasPricePercentage calculates the gas price's effective percentage
|
| 22 |
+
func CalculateEffectiveGasPricePercentage(gasPrice *big.Int, effectiveGasPrice *big.Int) (uint8, error) {
|
| 23 |
+
const bits = 256
|
| 24 |
+
var bitsBigInt = big.NewInt(bits)
|
| 25 |
+
|
| 26 |
+
if effectiveGasPrice == nil || gasPrice == nil ||
|
| 27 |
+
gasPrice.Cmp(big.NewInt(0)) == 0 || effectiveGasPrice.Cmp(big.NewInt(0)) == 0 {
|
| 28 |
+
return 0, ErrEffectiveGasPriceEmpty
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
if gasPrice.Cmp(effectiveGasPrice) <= 0 {
|
| 32 |
+
return MaxEffectivePercentage, nil
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
// Simulate Ceil with integer division
|
| 36 |
+
b := new(big.Int).Mul(effectiveGasPrice, bitsBigInt)
|
| 37 |
+
b = b.Add(b, gasPrice)
|
| 38 |
+
b = b.Sub(b, big.NewInt(1)) //nolint:gomnd
|
| 39 |
+
b = b.Div(b, gasPrice)
|
| 40 |
+
// At this point we have a percentage between 1-256, we need to sub 1 to have it between 0-255 (byte)
|
| 41 |
+
b = b.Sub(b, big.NewInt(1)) //nolint:gomnd
|
| 42 |
+
|
| 43 |
+
return uint8(b.Uint64()), nil
|
| 44 |
+
}
|
|
@@ -19,8 +19,10 @@
|
|
| 19 |
|
| 20 |
// Genesis contains the information to populate state on creation
|
| 21 |
type Genesis struct {
|
| 22 |
-
//
|
| 23 |
-
|
|
|
|
|
|
|
| 24 |
// Root hash of the genesis block
|
| 25 |
Root common.Hash
|
| 26 |
// Actions is the data to populate into the state trie
|
|
|
|
| 19 |
|
| 20 |
// Genesis contains the information to populate state on creation
|
| 21 |
type Genesis struct {
|
| 22 |
+
// RollupBlockNumber is the block number where the polygonZKEVM smc was deployed on L1
|
| 23 |
+
RollupBlockNumber uint64
|
| 24 |
+
// RollupManagerBlockNumber is the block number where the RollupManager smc was deployed on L1
|
| 25 |
+
RollupManagerBlockNumber uint64
|
| 26 |
// Root hash of the genesis block
|
| 27 |
Root common.Hash
|
| 28 |
// Actions is the data to populate into the state trie
|
|
@@ -18,8 +18,6 @@
|
|
| 18 |
double = 2
|
| 19 |
ether155V = 27
|
| 20 |
etherPre155V = 35
|
| 21 |
-
// MaxEffectivePercentage is the maximum value that can be used as effective percentage
|
| 22 |
-
MaxEffectivePercentage = uint8(255)
|
| 23 |
// Decoding constants
|
| 24 |
headerByteLength uint64 = 1
|
| 25 |
sLength uint64 = 32
|
|
|
|
| 18 |
double = 2
|
| 19 |
ether155V = 27
|
| 20 |
etherPre155V = 35
|
|
|
|
|
|
|
| 21 |
// Decoding constants
|
| 22 |
headerByteLength uint64 = 1
|
| 23 |
sLength uint64 = 32
|
|
@@ -24,6 +24,9 @@
|
|
| 24 |
GetTxsOlderThanNL1BlocksUntilTxHash(ctx context.Context, nL1Blocks uint64, earliestTxHash common.Hash, dbTx pgx.Tx) ([]common.Hash, error)
|
| 25 |
GetLastBlock(ctx context.Context, dbTx pgx.Tx) (*Block, error)
|
| 26 |
GetPreviousBlock(ctx context.Context, offset uint64, dbTx pgx.Tx) (*Block, error)
|
|
|
|
|
|
|
|
|
|
| 27 |
AddGlobalExitRoot(ctx context.Context, exitRoot *GlobalExitRoot, dbTx pgx.Tx) error
|
| 28 |
GetLatestGlobalExitRoot(ctx context.Context, maxBlockNumber uint64, dbTx pgx.Tx) (GlobalExitRoot, time.Time, error)
|
| 29 |
GetNumberOfBlocksSinceLastGERUpdate(ctx context.Context, dbTx pgx.Tx) (uint64, error)
|
|
@@ -146,10 +149,13 @@
|
|
| 146 |
GetRawBatchTimestamps(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*time.Time, *time.Time, error)
|
| 147 |
GetL1InfoRootLeafByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) (L1InfoTreeExitRootStorageEntry, error)
|
| 148 |
GetL1InfoRootLeafByIndex(ctx context.Context, l1InfoTreeIndex uint32, dbTx pgx.Tx) (L1InfoTreeExitRootStorageEntry, error)
|
| 149 |
-
|
| 150 |
GetBlockByNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (*Block, error)
|
| 151 |
GetVirtualBatchParentHash(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (common.Hash, error)
|
| 152 |
GetForcedBatchParentHash(ctx context.Context, forcedBatchNumber uint64, dbTx pgx.Tx) (common.Hash, error)
|
|
|
|
|
|
|
|
|
|
| 153 |
GetLatestBatchGlobalExitRoot(ctx context.Context, dbTx pgx.Tx) (common.Hash, error)
|
| 154 |
GetL2TxHashByTxHash(ctx context.Context, hash common.Hash, dbTx pgx.Tx) (*common.Hash, error)
|
| 155 |
GetSyncInfoData(ctx context.Context, dbTx pgx.Tx) (SyncInfoDataOnStorage, error)
|
|
@@ -159,4 +165,5 @@
|
|
| 159 |
UpdateBatchAsChecked(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) error
|
| 160 |
GetNotCheckedBatches(ctx context.Context, dbTx pgx.Tx) ([]*Batch, error)
|
| 161 |
GetLastL2BlockByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*L2Block, error)
|
|
|
|
| 162 |
}
|
|
|
|
| 24 |
GetTxsOlderThanNL1BlocksUntilTxHash(ctx context.Context, nL1Blocks uint64, earliestTxHash common.Hash, dbTx pgx.Tx) ([]common.Hash, error)
|
| 25 |
GetLastBlock(ctx context.Context, dbTx pgx.Tx) (*Block, error)
|
| 26 |
GetPreviousBlock(ctx context.Context, offset uint64, dbTx pgx.Tx) (*Block, error)
|
| 27 |
+
GetFirstUncheckedBlock(ctx context.Context, fromBlockNumber uint64, dbTx pgx.Tx) (*Block, error)
|
| 28 |
+
GetUncheckedBlocks(ctx context.Context, fromBlockNumber uint64, toBlockNumber uint64, dbTx pgx.Tx) ([]*Block, error)
|
| 29 |
+
UpdateCheckedBlockByNumber(ctx context.Context, blockNumber uint64, newCheckedStatus bool, dbTx pgx.Tx) error
|
| 30 |
AddGlobalExitRoot(ctx context.Context, exitRoot *GlobalExitRoot, dbTx pgx.Tx) error
|
| 31 |
GetLatestGlobalExitRoot(ctx context.Context, maxBlockNumber uint64, dbTx pgx.Tx) (GlobalExitRoot, time.Time, error)
|
| 32 |
GetNumberOfBlocksSinceLastGERUpdate(ctx context.Context, dbTx pgx.Tx) (uint64, error)
|
|
|
|
| 149 |
GetRawBatchTimestamps(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*time.Time, *time.Time, error)
|
| 150 |
GetL1InfoRootLeafByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) (L1InfoTreeExitRootStorageEntry, error)
|
| 151 |
GetL1InfoRootLeafByIndex(ctx context.Context, l1InfoTreeIndex uint32, dbTx pgx.Tx) (L1InfoTreeExitRootStorageEntry, error)
|
| 152 |
+
GetLeavesByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) ([]L1InfoTreeExitRootStorageEntry, error)
|
| 153 |
GetBlockByNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (*Block, error)
|
| 154 |
GetVirtualBatchParentHash(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (common.Hash, error)
|
| 155 |
GetForcedBatchParentHash(ctx context.Context, forcedBatchNumber uint64, dbTx pgx.Tx) (common.Hash, error)
|
| 156 |
+
GetBatchL2DataByNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) ([]byte, error)
|
| 157 |
+
GetBatchL2DataByNumbers(ctx context.Context, batchNumbers []uint64, dbTx pgx.Tx) (map[uint64][]byte, error)
|
| 158 |
+
GetForcedBatchDataByNumbers(ctx context.Context, batchNumbers []uint64, dbTx pgx.Tx) (map[uint64][]byte, error)
|
| 159 |
GetLatestBatchGlobalExitRoot(ctx context.Context, dbTx pgx.Tx) (common.Hash, error)
|
| 160 |
GetL2TxHashByTxHash(ctx context.Context, hash common.Hash, dbTx pgx.Tx) (*common.Hash, error)
|
| 161 |
GetSyncInfoData(ctx context.Context, dbTx pgx.Tx) (SyncInfoDataOnStorage, error)
|
|
|
|
| 165 |
UpdateBatchAsChecked(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) error
|
| 166 |
GetNotCheckedBatches(ctx context.Context, dbTx pgx.Tx) ([]*Batch, error)
|
| 167 |
GetLastL2BlockByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*L2Block, error)
|
| 168 |
+
GetPreviousBlockToBlockNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (*Block, error)
|
| 169 |
}
|
|
@@ -34,20 +34,20 @@
|
|
| 34 |
if s.l1InfoTree != nil {
|
| 35 |
return nil
|
| 36 |
}
|
| 37 |
-
|
| 38 |
-
allLeaves, err := s.
|
| 39 |
if err != nil {
|
| 40 |
-
log.Error("error getting all leaves. Error: ", err)
|
| 41 |
-
return
|
| 42 |
}
|
| 43 |
var leaves [][32]byte
|
| 44 |
for _, leaf := range allLeaves {
|
| 45 |
leaves = append(leaves, leaf.Hash())
|
| 46 |
}
|
| 47 |
-
mt, err :=
|
| 48 |
if err != nil {
|
| 49 |
-
log.Error("error
|
| 50 |
-
return
|
| 51 |
}
|
| 52 |
s.l1InfoTree = mt
|
| 53 |
return nil
|
|
@@ -55,6 +55,14 @@
|
|
| 55 |
|
| 56 |
// AddL1InfoTreeLeaf adds a new leaf to the L1InfoTree and returns the entry and error
|
| 57 |
func (s *State) AddL1InfoTreeLeaf(ctx context.Context, l1InfoTreeLeaf *L1InfoTreeLeaf, dbTx pgx.Tx) (*L1InfoTreeExitRootStorageEntry, error) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
var newIndex uint32
|
| 59 |
gerIndex, err := s.GetLatestIndex(ctx, dbTx)
|
| 60 |
if err != nil && !errors.Is(err, ErrNotFound) {
|
|
@@ -74,6 +82,9 @@
|
|
| 74 |
log.Error("error add new leaf to the L1InfoTree. Error: ", err)
|
| 75 |
return nil, err
|
| 76 |
}
|
|
|
|
|
|
|
|
|
|
| 77 |
entry := L1InfoTreeExitRootStorageEntry{
|
| 78 |
L1InfoTreeLeaf: *l1InfoTreeLeaf,
|
| 79 |
L1InfoTreeRoot: root,
|
|
|
|
| 34 |
if s.l1InfoTree != nil {
|
| 35 |
return nil
|
| 36 |
}
|
| 37 |
+
// Reset L1InfoTree siblings and leaves
|
| 38 |
+
allLeaves, err := s.GetAllL1InfoRootEntries(ctx, dbTx)
|
| 39 |
if err != nil {
|
| 40 |
+
log.Error("error getting all leaves to reset l1InfoTree. Error: ", err)
|
| 41 |
+
return err
|
| 42 |
}
|
| 43 |
var leaves [][32]byte
|
| 44 |
for _, leaf := range allLeaves {
|
| 45 |
leaves = append(leaves, leaf.Hash())
|
| 46 |
}
|
| 47 |
+
mt, err := s.l1InfoTree.ResetL1InfoTree(leaves)
|
| 48 |
if err != nil {
|
| 49 |
+
log.Error("error resetting l1InfoTree. Error: ", err)
|
| 50 |
+
return err
|
| 51 |
}
|
| 52 |
s.l1InfoTree = mt
|
| 53 |
return nil
|
|
|
|
| 55 |
|
| 56 |
// AddL1InfoTreeLeaf adds a new leaf to the L1InfoTree and returns the entry and error
|
| 57 |
func (s *State) AddL1InfoTreeLeaf(ctx context.Context, l1InfoTreeLeaf *L1InfoTreeLeaf, dbTx pgx.Tx) (*L1InfoTreeExitRootStorageEntry, error) {
|
| 58 |
+
var stateTx *StateTx
|
| 59 |
+
if dbTx != nil {
|
| 60 |
+
var ok bool
|
| 61 |
+
stateTx, ok = dbTx.(*StateTx)
|
| 62 |
+
if !ok {
|
| 63 |
+
return nil, fmt.Errorf("error casting dbTx to stateTx")
|
| 64 |
+
}
|
| 65 |
+
}
|
| 66 |
var newIndex uint32
|
| 67 |
gerIndex, err := s.GetLatestIndex(ctx, dbTx)
|
| 68 |
if err != nil && !errors.Is(err, ErrNotFound) {
|
|
|
|
| 82 |
log.Error("error add new leaf to the L1InfoTree. Error: ", err)
|
| 83 |
return nil, err
|
| 84 |
}
|
| 85 |
+
if stateTx != nil {
|
| 86 |
+
stateTx.SetL1InfoTreeModified()
|
| 87 |
+
}
|
| 88 |
entry := L1InfoTreeExitRootStorageEntry{
|
| 89 |
L1InfoTreeLeaf: *l1InfoTreeLeaf,
|
| 90 |
L1InfoTreeRoot: root,
|
|
@@ -16,10 +16,10 @@
|
|
| 16 |
|
| 17 |
// AddBlock adds a new block to the State Store
|
| 18 |
func (p *PostgresStorage) AddBlock(ctx context.Context, block *state.Block, dbTx pgx.Tx) error {
|
| 19 |
-
const addBlockSQL = "INSERT INTO state.block (block_num, block_hash, parent_hash, received_at) VALUES ($1, $2, $3, $4)"
|
| 20 |
|
| 21 |
e := p.getExecQuerier(dbTx)
|
| 22 |
-
_, err := e.Exec(ctx, addBlockSQL, block.BlockNumber, block.BlockHash.String(), block.ParentHash.String(), block.ReceivedAt)
|
| 23 |
return err
|
| 24 |
}
|
| 25 |
|
|
@@ -30,11 +30,11 @@
|
|
| 30 |
parentHash string
|
| 31 |
block state.Block
|
| 32 |
)
|
| 33 |
-
const getLastBlockSQL = "SELECT block_num, block_hash, parent_hash, received_at FROM state.block ORDER BY block_num DESC LIMIT 1"
|
| 34 |
|
| 35 |
q := p.getExecQuerier(dbTx)
|
| 36 |
|
| 37 |
-
err := q.QueryRow(ctx, getLastBlockSQL).Scan(&block.BlockNumber, &blockHash, &parentHash, &block.ReceivedAt)
|
| 38 |
if errors.Is(err, pgx.ErrNoRows) {
|
| 39 |
return nil, state.ErrStateNotSynchronized
|
| 40 |
}
|
|
@@ -43,6 +43,55 @@
|
|
| 43 |
return &block, err
|
| 44 |
}
|
| 45 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
// GetPreviousBlock gets the offset previous L1 block respect to latest.
|
| 47 |
func (p *PostgresStorage) GetPreviousBlock(ctx context.Context, offset uint64, dbTx pgx.Tx) (*state.Block, error) {
|
| 48 |
var (
|
|
@@ -50,11 +99,31 @@
|
|
| 50 |
parentHash string
|
| 51 |
block state.Block
|
| 52 |
)
|
| 53 |
-
const getPreviousBlockSQL = "SELECT block_num, block_hash, parent_hash, received_at FROM state.block ORDER BY block_num DESC LIMIT 1 OFFSET $1"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
|
| 55 |
q := p.getExecQuerier(dbTx)
|
| 56 |
|
| 57 |
-
err := q.QueryRow(ctx, getPreviousBlockSQL,
|
| 58 |
if errors.Is(err, pgx.ErrNoRows) {
|
| 59 |
return nil, state.ErrNotFound
|
| 60 |
}
|
|
@@ -70,11 +139,11 @@
|
|
| 70 |
parentHash string
|
| 71 |
block state.Block
|
| 72 |
)
|
| 73 |
-
const getBlockByNumberSQL = "SELECT block_num, block_hash, parent_hash, received_at FROM state.block WHERE block_num = $1"
|
| 74 |
|
| 75 |
q := p.getExecQuerier(dbTx)
|
| 76 |
|
| 77 |
-
err := q.QueryRow(ctx, getBlockByNumberSQL, blockNumber).Scan(&block.BlockNumber, &blockHash, &parentHash, &block.ReceivedAt)
|
| 78 |
if errors.Is(err, pgx.ErrNoRows) {
|
| 79 |
return nil, state.ErrNotFound
|
| 80 |
}
|
|
@@ -82,3 +151,14 @@
|
|
| 82 |
block.ParentHash = common.HexToHash(parentHash)
|
| 83 |
return &block, err
|
| 84 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
|
| 17 |
// AddBlock adds a new block to the State Store
|
| 18 |
func (p *PostgresStorage) AddBlock(ctx context.Context, block *state.Block, dbTx pgx.Tx) error {
|
| 19 |
+
const addBlockSQL = "INSERT INTO state.block (block_num, block_hash, parent_hash, received_at, checked) VALUES ($1, $2, $3, $4, $5)"
|
| 20 |
|
| 21 |
e := p.getExecQuerier(dbTx)
|
| 22 |
+
_, err := e.Exec(ctx, addBlockSQL, block.BlockNumber, block.BlockHash.String(), block.ParentHash.String(), block.ReceivedAt, block.Checked)
|
| 23 |
return err
|
| 24 |
}
|
| 25 |
|
|
|
|
| 30 |
parentHash string
|
| 31 |
block state.Block
|
| 32 |
)
|
| 33 |
+
const getLastBlockSQL = "SELECT block_num, block_hash, parent_hash, received_at, checked FROM state.block ORDER BY block_num DESC LIMIT 1"
|
| 34 |
|
| 35 |
q := p.getExecQuerier(dbTx)
|
| 36 |
|
| 37 |
+
err := q.QueryRow(ctx, getLastBlockSQL).Scan(&block.BlockNumber, &blockHash, &parentHash, &block.ReceivedAt, &block.Checked)
|
| 38 |
if errors.Is(err, pgx.ErrNoRows) {
|
| 39 |
return nil, state.ErrStateNotSynchronized
|
| 40 |
}
|
|
|
|
| 43 |
return &block, err
|
| 44 |
}
|
| 45 |
|
| 46 |
+
// GetFirstUncheckedBlock returns the first L1 block that has not been checked from a given block number.
|
| 47 |
+
func (p *PostgresStorage) GetFirstUncheckedBlock(ctx context.Context, fromBlockNumber uint64, dbTx pgx.Tx) (*state.Block, error) {
|
| 48 |
+
var (
|
| 49 |
+
blockHash string
|
| 50 |
+
parentHash string
|
| 51 |
+
block state.Block
|
| 52 |
+
)
|
| 53 |
+
const getLastBlockSQL = "SELECT block_num, block_hash, parent_hash, received_at, checked FROM state.block WHERE block_num>=$1 AND checked=false ORDER BY block_num LIMIT 1"
|
| 54 |
+
|
| 55 |
+
q := p.getExecQuerier(dbTx)
|
| 56 |
+
|
| 57 |
+
err := q.QueryRow(ctx, getLastBlockSQL, fromBlockNumber).Scan(&block.BlockNumber, &blockHash, &parentHash, &block.ReceivedAt, &block.Checked)
|
| 58 |
+
if errors.Is(err, pgx.ErrNoRows) {
|
| 59 |
+
return nil, state.ErrNotFound
|
| 60 |
+
}
|
| 61 |
+
block.BlockHash = common.HexToHash(blockHash)
|
| 62 |
+
block.ParentHash = common.HexToHash(parentHash)
|
| 63 |
+
return &block, err
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
func (p *PostgresStorage) GetUncheckedBlocks(ctx context.Context, fromBlockNumber uint64, toBlockNumber uint64, dbTx pgx.Tx) ([]*state.Block, error) {
|
| 67 |
+
const getUncheckedBlocksSQL = "SELECT block_num, block_hash, parent_hash, received_at, checked FROM state.block WHERE block_num>=$1 AND block_num<=$2 AND checked=false ORDER BY block_num"
|
| 68 |
+
|
| 69 |
+
q := p.getExecQuerier(dbTx)
|
| 70 |
+
|
| 71 |
+
rows, err := q.Query(ctx, getUncheckedBlocksSQL, fromBlockNumber, toBlockNumber)
|
| 72 |
+
if err != nil {
|
| 73 |
+
return nil, err
|
| 74 |
+
}
|
| 75 |
+
defer rows.Close()
|
| 76 |
+
|
| 77 |
+
var blocks []*state.Block
|
| 78 |
+
for rows.Next() {
|
| 79 |
+
var (
|
| 80 |
+
blockHash string
|
| 81 |
+
parentHash string
|
| 82 |
+
block state.Block
|
| 83 |
+
)
|
| 84 |
+
err := rows.Scan(&block.BlockNumber, &blockHash, &parentHash, &block.ReceivedAt, &block.Checked)
|
| 85 |
+
if err != nil {
|
| 86 |
+
return nil, err
|
| 87 |
+
}
|
| 88 |
+
block.BlockHash = common.HexToHash(blockHash)
|
| 89 |
+
block.ParentHash = common.HexToHash(parentHash)
|
| 90 |
+
blocks = append(blocks, &block)
|
| 91 |
+
}
|
| 92 |
+
return blocks, nil
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
// GetPreviousBlock gets the offset previous L1 block respect to latest.
|
| 96 |
func (p *PostgresStorage) GetPreviousBlock(ctx context.Context, offset uint64, dbTx pgx.Tx) (*state.Block, error) {
|
| 97 |
var (
|
|
|
|
| 99 |
parentHash string
|
| 100 |
block state.Block
|
| 101 |
)
|
| 102 |
+
const getPreviousBlockSQL = "SELECT block_num, block_hash, parent_hash, received_at,checked FROM state.block ORDER BY block_num DESC LIMIT 1 OFFSET $1"
|
| 103 |
+
|
| 104 |
+
q := p.getExecQuerier(dbTx)
|
| 105 |
+
|
| 106 |
+
err := q.QueryRow(ctx, getPreviousBlockSQL, offset).Scan(&block.BlockNumber, &blockHash, &parentHash, &block.ReceivedAt, &block.Checked)
|
| 107 |
+
if errors.Is(err, pgx.ErrNoRows) {
|
| 108 |
+
return nil, state.ErrNotFound
|
| 109 |
+
}
|
| 110 |
+
block.BlockHash = common.HexToHash(blockHash)
|
| 111 |
+
block.ParentHash = common.HexToHash(parentHash)
|
| 112 |
+
return &block, err
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
// GetPreviousBlockToBlockNumber gets the previous L1 block respect blockNumber.
|
| 116 |
+
func (p *PostgresStorage) GetPreviousBlockToBlockNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (*state.Block, error) {
|
| 117 |
+
var (
|
| 118 |
+
blockHash string
|
| 119 |
+
parentHash string
|
| 120 |
+
block state.Block
|
| 121 |
+
)
|
| 122 |
+
const getPreviousBlockSQL = "SELECT block_num, block_hash, parent_hash, received_at,checked FROM state.block WHERE block_num < $1 ORDER BY block_num DESC LIMIT 1 "
|
| 123 |
|
| 124 |
q := p.getExecQuerier(dbTx)
|
| 125 |
|
| 126 |
+
err := q.QueryRow(ctx, getPreviousBlockSQL, blockNumber).Scan(&block.BlockNumber, &blockHash, &parentHash, &block.ReceivedAt, &block.Checked)
|
| 127 |
if errors.Is(err, pgx.ErrNoRows) {
|
| 128 |
return nil, state.ErrNotFound
|
| 129 |
}
|
|
|
|
| 139 |
parentHash string
|
| 140 |
block state.Block
|
| 141 |
)
|
| 142 |
+
const getBlockByNumberSQL = "SELECT block_num, block_hash, parent_hash, received_at,checked FROM state.block WHERE block_num = $1"
|
| 143 |
|
| 144 |
q := p.getExecQuerier(dbTx)
|
| 145 |
|
| 146 |
+
err := q.QueryRow(ctx, getBlockByNumberSQL, blockNumber).Scan(&block.BlockNumber, &blockHash, &parentHash, &block.ReceivedAt, &block.Checked)
|
| 147 |
if errors.Is(err, pgx.ErrNoRows) {
|
| 148 |
return nil, state.ErrNotFound
|
| 149 |
}
|
|
|
|
| 151 |
block.ParentHash = common.HexToHash(parentHash)
|
| 152 |
return &block, err
|
| 153 |
}
|
| 154 |
+
|
| 155 |
+
// UpdateCheckedBlockByNumber update checked flag for a block
|
| 156 |
+
func (p *PostgresStorage) UpdateCheckedBlockByNumber(ctx context.Context, blockNumber uint64, newCheckedStatus bool, dbTx pgx.Tx) error {
|
| 157 |
+
const query = `
|
| 158 |
+
UPDATE state.block
|
| 159 |
+
SET checked = $1 WHERE block_num = $2`
|
| 160 |
+
|
| 161 |
+
e := p.getExecQuerier(dbTx)
|
| 162 |
+
_, err := e.Exec(ctx, query, newCheckedStatus, blockNumber)
|
| 163 |
+
return err
|
| 164 |
+
}
|
|
@@ -53,7 +53,7 @@
|
|
| 53 |
const getL1InfoRootSQL = `SELECT block_num, timestamp, mainnet_exit_root, rollup_exit_root, global_exit_root, prev_block_hash, l1_info_root, l1_info_tree_index
|
| 54 |
FROM state.exit_root
|
| 55 |
WHERE l1_info_tree_index IS NOT NULL AND block_num <= $1
|
| 56 |
-
ORDER BY l1_info_tree_index DESC`
|
| 57 |
|
| 58 |
entry := state.L1InfoTreeExitRootStorageEntry{}
|
| 59 |
|
|
@@ -112,7 +112,7 @@
|
|
| 112 |
return entry, nil
|
| 113 |
}
|
| 114 |
|
| 115 |
-
func (p *PostgresStorage)
|
| 116 |
// TODO: Optimize this query
|
| 117 |
const getLeafsByL1InfoRootSQL = `SELECT block_num, timestamp, mainnet_exit_root, rollup_exit_root, global_exit_root, prev_block_hash, l1_info_root, l1_info_tree_index
|
| 118 |
FROM state.exit_root
|
|
|
|
| 53 |
const getL1InfoRootSQL = `SELECT block_num, timestamp, mainnet_exit_root, rollup_exit_root, global_exit_root, prev_block_hash, l1_info_root, l1_info_tree_index
|
| 54 |
FROM state.exit_root
|
| 55 |
WHERE l1_info_tree_index IS NOT NULL AND block_num <= $1
|
| 56 |
+
ORDER BY l1_info_tree_index DESC LIMIT 1`
|
| 57 |
|
| 58 |
entry := state.L1InfoTreeExitRootStorageEntry{}
|
| 59 |
|
|
|
|
| 112 |
return entry, nil
|
| 113 |
}
|
| 114 |
|
| 115 |
+
func (p *PostgresStorage) GetLeavesByL1InfoRoot(ctx context.Context, l1InfoRoot common.Hash, dbTx pgx.Tx) ([]state.L1InfoTreeExitRootStorageEntry, error) {
|
| 116 |
// TODO: Optimize this query
|
| 117 |
const getLeafsByL1InfoRootSQL = `SELECT block_num, timestamp, mainnet_exit_root, rollup_exit_root, global_exit_root, prev_block_hash, l1_info_root, l1_info_tree_index
|
| 118 |
FROM state.exit_root
|
|
@@ -119,7 +119,7 @@
|
|
| 119 |
return common.HexToHash(stateRootStr), nil
|
| 120 |
}
|
| 121 |
|
| 122 |
-
// GetLogsByBlockNumber get all the logs from a specific block ordered by log index
|
| 123 |
func (p *PostgresStorage) GetLogsByBlockNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) ([]*types.Log, error) {
|
| 124 |
const query = `
|
| 125 |
SELECT t.l2_block_num, b.block_hash, l.tx_hash, r.tx_index, l.log_index, l.address, l.data, l.topic0, l.topic1, l.topic2, l.topic3
|
|
@@ -128,7 +128,7 @@
|
|
| 128 |
INNER JOIN state.l2block b ON b.block_num = t.l2_block_num
|
| 129 |
INNER JOIN state.receipt r ON r.tx_hash = t.hash
|
| 130 |
WHERE b.block_num = $1
|
| 131 |
-
ORDER BY l.log_index ASC`
|
| 132 |
|
| 133 |
q := p.getExecQuerier(dbTx)
|
| 134 |
rows, err := q.Query(ctx, query, blockNumber)
|
|
@@ -159,7 +159,7 @@
|
|
| 159 |
const queryFilterByBlockHash = `AND b.block_hash = $7 `
|
| 160 |
const queryFilterByBlockNumbers = `AND b.block_num BETWEEN $7 AND $8 `
|
| 161 |
|
| 162 |
-
const queryOrder = `ORDER BY b.block_num ASC, l.log_index ASC`
|
| 163 |
|
| 164 |
// count queries
|
| 165 |
const queryToCountLogsByBlockHash = "" +
|
|
@@ -355,3 +355,87 @@
|
|
| 355 |
}
|
| 356 |
return nativeBlockHashes, nil
|
| 357 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
return common.HexToHash(stateRootStr), nil
|
| 120 |
}
|
| 121 |
|
| 122 |
+
// GetLogsByBlockNumber get all the logs from a specific block ordered by tx index and log index
|
| 123 |
func (p *PostgresStorage) GetLogsByBlockNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) ([]*types.Log, error) {
|
| 124 |
const query = `
|
| 125 |
SELECT t.l2_block_num, b.block_hash, l.tx_hash, r.tx_index, l.log_index, l.address, l.data, l.topic0, l.topic1, l.topic2, l.topic3
|
|
|
|
| 128 |
INNER JOIN state.l2block b ON b.block_num = t.l2_block_num
|
| 129 |
INNER JOIN state.receipt r ON r.tx_hash = t.hash
|
| 130 |
WHERE b.block_num = $1
|
| 131 |
+
ORDER BY r.tx_index ASC, l.log_index ASC`
|
| 132 |
|
| 133 |
q := p.getExecQuerier(dbTx)
|
| 134 |
rows, err := q.Query(ctx, query, blockNumber)
|
|
|
|
| 159 |
const queryFilterByBlockHash = `AND b.block_hash = $7 `
|
| 160 |
const queryFilterByBlockNumbers = `AND b.block_num BETWEEN $7 AND $8 `
|
| 161 |
|
| 162 |
+
const queryOrder = `ORDER BY b.block_num ASC, r.tx_index ASC, l.log_index ASC`
|
| 163 |
|
| 164 |
// count queries
|
| 165 |
const queryToCountLogsByBlockHash = "" +
|
|
|
|
| 355 |
}
|
| 356 |
return nativeBlockHashes, nil
|
| 357 |
}
|
| 358 |
+
|
| 359 |
+
// GetBatchL2DataByNumber returns the batch L2 data of the given batch number.
|
| 360 |
+
func (p *PostgresStorage) GetBatchL2DataByNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) ([]byte, error) {
|
| 361 |
+
batchData, err := p.GetBatchL2DataByNumbers(ctx, []uint64{batchNumber}, dbTx)
|
| 362 |
+
if err != nil {
|
| 363 |
+
return nil, err
|
| 364 |
+
}
|
| 365 |
+
data, ok := batchData[batchNumber]
|
| 366 |
+
if !ok {
|
| 367 |
+
return nil, state.ErrNotFound
|
| 368 |
+
}
|
| 369 |
+
return data, nil
|
| 370 |
+
}
|
| 371 |
+
|
| 372 |
+
// GetBatchL2DataByNumbers returns the batch L2 data of the given batch numbers. The data is a union of state.batch and state.forced_batch tables.
|
| 373 |
+
func (p *PostgresStorage) GetBatchL2DataByNumbers(ctx context.Context, batchNumbers []uint64, dbTx pgx.Tx) (map[uint64][]byte, error) {
|
| 374 |
+
const sql = "SELECT batch_num, raw_txs_data FROM state.batch WHERE batch_num = ANY($1)"
|
| 375 |
+
return p.getBatchData(ctx, sql, batchNumbers, dbTx)
|
| 376 |
+
}
|
| 377 |
+
|
| 378 |
+
// GetForcedBatchDataByNumbers returns the forced batch data of the given batch numbers
|
| 379 |
+
func (p *PostgresStorage) GetForcedBatchDataByNumbers(ctx context.Context, batchNumbers []uint64, dbTx pgx.Tx) (map[uint64][]byte, error) {
|
| 380 |
+
const sql = "SELECT forced_batch_num, convert_from(decode(raw_txs_data, 'hex'), 'UTF8')::bytea FROM state.forced_batch WHERE forced_batch_num = ANY($1)"
|
| 381 |
+
return p.getBatchData(ctx, sql, batchNumbers, dbTx)
|
| 382 |
+
}
|
| 383 |
+
|
| 384 |
+
func (p *PostgresStorage) getBatchData(ctx context.Context, sql string, batchNumbers []uint64, dbTx pgx.Tx) (map[uint64][]byte, error) {
|
| 385 |
+
q := p.getExecQuerier(dbTx)
|
| 386 |
+
rows, err := q.Query(ctx, sql, batchNumbers)
|
| 387 |
+
if errors.Is(err, pgx.ErrNoRows) {
|
| 388 |
+
return p.GetBatchL2DataByNumbersFromBackup(ctx, batchNumbers, dbTx)
|
| 389 |
+
} else if err != nil {
|
| 390 |
+
return nil, err
|
| 391 |
+
}
|
| 392 |
+
defer rows.Close()
|
| 393 |
+
|
| 394 |
+
batchL2DataMap, err := readBatchDataResults(rows, batchNumbers)
|
| 395 |
+
if err != nil {
|
| 396 |
+
return nil, err
|
| 397 |
+
}
|
| 398 |
+
|
| 399 |
+
if len(batchL2DataMap) == 0 {
|
| 400 |
+
return p.GetBatchL2DataByNumbersFromBackup(ctx, batchNumbers, dbTx)
|
| 401 |
+
}
|
| 402 |
+
|
| 403 |
+
return batchL2DataMap, nil
|
| 404 |
+
}
|
| 405 |
+
|
| 406 |
+
// GetBatchL2DataByNumbersFromBackup returns the batch L2 data of the given batch number from the backup table
|
| 407 |
+
func (p *PostgresStorage) GetBatchL2DataByNumbersFromBackup(ctx context.Context, batchNumbers []uint64, dbTx pgx.Tx) (map[uint64][]byte, error) {
|
| 408 |
+
getBatchL2DataByBatchNumber := `
|
| 409 |
+
SELECT batch_num, data FROM state.batch_data_backup
|
| 410 |
+
WHERE batch_num = ANY($1)
|
| 411 |
+
ORDER BY created_at DESC
|
| 412 |
+
`
|
| 413 |
+
q := p.getExecQuerier(dbTx)
|
| 414 |
+
rows, err := q.Query(ctx, getBatchL2DataByBatchNumber, batchNumbers)
|
| 415 |
+
if errors.Is(err, pgx.ErrNoRows) {
|
| 416 |
+
return nil, state.ErrNotFound
|
| 417 |
+
} else if err != nil {
|
| 418 |
+
return nil, err
|
| 419 |
+
}
|
| 420 |
+
defer rows.Close()
|
| 421 |
+
|
| 422 |
+
return readBatchDataResults(rows, batchNumbers)
|
| 423 |
+
}
|
| 424 |
+
|
| 425 |
+
// readBatchDataResults retrieves batch data from the provided result set
|
| 426 |
+
func readBatchDataResults(results pgx.Rows, batchNumbers []uint64) (map[uint64][]byte, error) {
|
| 427 |
+
batchL2DataMap := make(map[uint64][]byte, len(batchNumbers))
|
| 428 |
+
for results.Next() {
|
| 429 |
+
var (
|
| 430 |
+
batchNum uint64
|
| 431 |
+
batchL2Data []byte
|
| 432 |
+
)
|
| 433 |
+
|
| 434 |
+
if err := results.Scan(&batchNum, &batchL2Data); err != nil {
|
| 435 |
+
return nil, err
|
| 436 |
+
}
|
| 437 |
+
batchL2DataMap[batchNum] = batchL2Data
|
| 438 |
+
}
|
| 439 |
+
|
| 440 |
+
return batchL2DataMap, nil
|
| 441 |
+
}
|
|
@@ -872,7 +872,7 @@
|
|
| 872 |
ctx := context.Background()
|
| 873 |
|
| 874 |
cfg := state.Config{
|
| 875 |
-
MaxLogsCount:
|
| 876 |
MaxLogsBlockRange: 10,
|
| 877 |
ForkIDIntervals: stateCfg.ForkIDIntervals,
|
| 878 |
}
|
|
@@ -895,39 +895,69 @@
|
|
| 895 |
time := time.Now()
|
| 896 |
blockNumber := big.NewInt(1)
|
| 897 |
|
| 898 |
-
|
| 899 |
-
|
| 900 |
-
|
| 901 |
-
|
| 902 |
-
|
| 903 |
-
|
| 904 |
-
|
| 905 |
-
|
| 906 |
-
|
| 907 |
-
|
| 908 |
-
|
| 909 |
-
|
| 910 |
-
|
| 911 |
-
|
| 912 |
-
|
| 913 |
-
|
| 914 |
-
|
| 915 |
-
|
| 916 |
-
|
| 917 |
-
|
| 918 |
-
|
| 919 |
-
|
| 920 |
-
|
| 921 |
-
|
| 922 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 923 |
}
|
| 924 |
|
| 925 |
-
transactions := []*types.Transaction{tx}
|
| 926 |
-
receipts := []*types.Receipt{receipt}
|
| 927 |
-
stateRoots := []common.Hash{state.ZeroHash}
|
| 928 |
-
|
| 929 |
header := state.NewL2Header(&types.Header{
|
| 930 |
-
Number: big.NewInt(int64(
|
| 931 |
ParentHash: state.ZeroHash,
|
| 932 |
Coinbase: state.ZeroAddress,
|
| 933 |
Root: state.ZeroHash,
|
|
@@ -954,6 +984,8 @@
|
|
| 954 |
require.NoError(t, err)
|
| 955 |
}
|
| 956 |
|
|
|
|
|
|
|
| 957 |
type testCase struct {
|
| 958 |
name string
|
| 959 |
from uint64
|
|
@@ -988,20 +1020,227 @@
|
|
| 988 |
name: "logs returned successfully",
|
| 989 |
from: 1,
|
| 990 |
to: 2,
|
| 991 |
-
logCount:
|
| 992 |
expectedError: nil,
|
| 993 |
},
|
| 994 |
}
|
| 995 |
|
| 996 |
for _, testCase := range testCases {
|
| 997 |
t.Run(testCase.name, func(t *testing.T) {
|
| 998 |
-
logs, err := testState.GetLogs(ctx, testCase.from, testCase.to, []common.Address{}, [][]common.Hash{}, nil, nil,
|
| 999 |
-
|
| 1000 |
assert.Equal(t, testCase.logCount, len(logs))
|
| 1001 |
assert.Equal(t, testCase.expectedError, err)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1002 |
})
|
| 1003 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1004 |
require.NoError(t, dbTx.Commit(ctx))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1005 |
}
|
| 1006 |
|
| 1007 |
func TestGetNativeBlockHashesInRange(t *testing.T) {
|
|
@@ -1132,6 +1371,108 @@
|
|
| 1132 |
require.NoError(t, dbTx.Commit(ctx))
|
| 1133 |
}
|
| 1134 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1135 |
func createL1InfoTreeExitRootStorageEntryForTest(blockNumber uint64, index uint32) *state.L1InfoTreeExitRootStorageEntry {
|
| 1136 |
exitRoot := state.L1InfoTreeExitRootStorageEntry{
|
| 1137 |
L1InfoTreeLeaf: state.L1InfoTreeLeaf{
|
|
@@ -1333,6 +1674,13 @@
|
|
| 1333 |
require.Equal(t, uint64(2002), fb.BlockNumber)
|
| 1334 |
require.Equal(t, "0x717e05de47a87a7d1679e183f1c224150675f6302b7da4eaab526b2b91ae0761", fb.GlobalExitRoot.String())
|
| 1335 |
require.Equal(t, []byte{0xb}, fb.RawTxsData)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1336 |
}
|
| 1337 |
|
| 1338 |
func TestGetLastGER(t *testing.T) {
|
|
@@ -1409,5 +1757,99 @@
|
|
| 1409 |
ger, err = testState.GetLatestBatchGlobalExitRoot(ctx, dbTx)
|
| 1410 |
require.NoError(t, err)
|
| 1411 |
require.Equal(t, common.HexToHash("0x2").String(), ger.String())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1412 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1413 |
}
|
|
|
|
| 872 |
ctx := context.Background()
|
| 873 |
|
| 874 |
cfg := state.Config{
|
| 875 |
+
MaxLogsCount: 40,
|
| 876 |
MaxLogsBlockRange: 10,
|
| 877 |
ForkIDIntervals: stateCfg.ForkIDIntervals,
|
| 878 |
}
|
|
|
|
| 895 |
time := time.Now()
|
| 896 |
blockNumber := big.NewInt(1)
|
| 897 |
|
| 898 |
+
maxBlocks := 3
|
| 899 |
+
txsPerBlock := 4
|
| 900 |
+
logsPerTx := 5
|
| 901 |
+
|
| 902 |
+
nonce := uint64(0)
|
| 903 |
+
|
| 904 |
+
// number of blocks to be created
|
| 905 |
+
for b := 0; b < maxBlocks; b++ {
|
| 906 |
+
logIndex := uint(0)
|
| 907 |
+
transactions := make([]*types.Transaction, 0, txsPerBlock)
|
| 908 |
+
receipts := make([]*types.Receipt, 0, txsPerBlock)
|
| 909 |
+
stateRoots := make([]common.Hash, 0, txsPerBlock)
|
| 910 |
+
|
| 911 |
+
// number of transactions in a block to be created
|
| 912 |
+
for t := 0; t < txsPerBlock; t++ {
|
| 913 |
+
nonce++
|
| 914 |
+
txIndex := uint(t + 1)
|
| 915 |
+
|
| 916 |
+
tx := types.NewTx(&types.LegacyTx{
|
| 917 |
+
Nonce: nonce,
|
| 918 |
+
To: nil,
|
| 919 |
+
Value: new(big.Int),
|
| 920 |
+
Gas: 0,
|
| 921 |
+
GasPrice: big.NewInt(0),
|
| 922 |
+
})
|
| 923 |
+
|
| 924 |
+
logs := []*types.Log{}
|
| 925 |
+
|
| 926 |
+
// if block is even logIndex follows a sequence related to the block
|
| 927 |
+
// for odd blocks logIndex follows a sequence related ot the tx
|
| 928 |
+
// this is needed to simulate a logIndex difference introduced on Etrog
|
| 929 |
+
// and we need to maintain to be able to synchronize these blocks
|
| 930 |
+
// number of logs in a transaction to be created
|
| 931 |
+
for l := 0; l < logsPerTx; l++ {
|
| 932 |
+
li := logIndex
|
| 933 |
+
if b%2 != 0 { // even block
|
| 934 |
+
li = uint(l)
|
| 935 |
+
}
|
| 936 |
+
|
| 937 |
+
logs = append(logs, &types.Log{TxHash: tx.Hash(), TxIndex: txIndex, Index: li})
|
| 938 |
+
logIndex++
|
| 939 |
+
}
|
| 940 |
+
|
| 941 |
+
receipt := &types.Receipt{
|
| 942 |
+
Type: tx.Type(),
|
| 943 |
+
PostState: state.ZeroHash.Bytes(),
|
| 944 |
+
CumulativeGasUsed: 0,
|
| 945 |
+
EffectiveGasPrice: big.NewInt(0),
|
| 946 |
+
BlockNumber: blockNumber,
|
| 947 |
+
GasUsed: tx.Gas(),
|
| 948 |
+
TxHash: tx.Hash(),
|
| 949 |
+
TransactionIndex: txIndex,
|
| 950 |
+
Status: types.ReceiptStatusSuccessful,
|
| 951 |
+
Logs: logs,
|
| 952 |
+
}
|
| 953 |
+
|
| 954 |
+
transactions = append(transactions, tx)
|
| 955 |
+
receipts = append(receipts, receipt)
|
| 956 |
+
stateRoots = append(stateRoots, state.ZeroHash)
|
| 957 |
}
|
| 958 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 959 |
header := state.NewL2Header(&types.Header{
|
| 960 |
+
Number: big.NewInt(int64(b) + 1),
|
| 961 |
ParentHash: state.ZeroHash,
|
| 962 |
Coinbase: state.ZeroAddress,
|
| 963 |
Root: state.ZeroHash,
|
|
|
|
| 984 |
require.NoError(t, err)
|
| 985 |
}
|
| 986 |
|
| 987 |
+
require.NoError(t, dbTx.Commit(ctx))
|
| 988 |
+
|
| 989 |
type testCase struct {
|
| 990 |
name string
|
| 991 |
from uint64
|
|
|
|
| 1020 |
name: "logs returned successfully",
|
| 1021 |
from: 1,
|
| 1022 |
to: 2,
|
| 1023 |
+
logCount: 40,
|
| 1024 |
expectedError: nil,
|
| 1025 |
},
|
| 1026 |
}
|
| 1027 |
|
| 1028 |
for _, testCase := range testCases {
|
| 1029 |
t.Run(testCase.name, func(t *testing.T) {
|
| 1030 |
+
logs, err := testState.GetLogs(ctx, testCase.from, testCase.to, []common.Address{}, [][]common.Hash{}, nil, nil, nil)
|
|
|
|
| 1031 |
assert.Equal(t, testCase.logCount, len(logs))
|
| 1032 |
assert.Equal(t, testCase.expectedError, err)
|
| 1033 |
+
|
| 1034 |
+
// check tx index and log index order
|
| 1035 |
+
lastBlockNumber := uint64(0)
|
| 1036 |
+
lastTxIndex := uint(0)
|
| 1037 |
+
lastLogIndex := uint(0)
|
| 1038 |
+
|
| 1039 |
+
for i, l := range logs {
|
| 1040 |
+
// if block has changed and it's not the first log, reset lastTxIndex
|
| 1041 |
+
if uint(l.BlockNumber) != uint(lastBlockNumber) && i != 0 {
|
| 1042 |
+
lastTxIndex = 0
|
| 1043 |
+
}
|
| 1044 |
+
|
| 1045 |
+
if l.TxIndex < lastTxIndex {
|
| 1046 |
+
t.Errorf("invalid tx index, expected greater than or equal to %v, but found %v", lastTxIndex, l.TxIndex)
|
| 1047 |
+
}
|
| 1048 |
+
// add tolerance for log index Etrog issue that was starting log indexes from 0 for each tx within a block
|
| 1049 |
+
// if tx index has changed and the log index starts on zero, than resets the lastLogIndex to zero
|
| 1050 |
+
if l.TxIndex != lastTxIndex && l.Index == 0 {
|
| 1051 |
+
lastLogIndex = 0
|
| 1052 |
+
}
|
| 1053 |
+
|
| 1054 |
+
if l.Index < lastLogIndex {
|
| 1055 |
+
t.Errorf("invalid log index, expected greater than %v, but found %v", lastLogIndex, l.Index)
|
| 1056 |
+
}
|
| 1057 |
+
|
| 1058 |
+
lastBlockNumber = l.BlockNumber
|
| 1059 |
+
lastTxIndex = l.TxIndex
|
| 1060 |
+
lastLogIndex = l.Index
|
| 1061 |
+
}
|
| 1062 |
})
|
| 1063 |
}
|
| 1064 |
+
}
|
| 1065 |
+
|
| 1066 |
+
func TestGetLogsByBlockNumber(t *testing.T) {
|
| 1067 |
+
initOrResetDB()
|
| 1068 |
+
|
| 1069 |
+
ctx := context.Background()
|
| 1070 |
+
|
| 1071 |
+
cfg := state.Config{
|
| 1072 |
+
MaxLogsCount: 40,
|
| 1073 |
+
MaxLogsBlockRange: 10,
|
| 1074 |
+
ForkIDIntervals: stateCfg.ForkIDIntervals,
|
| 1075 |
+
}
|
| 1076 |
+
|
| 1077 |
+
mt, err := l1infotree.NewL1InfoTree(32, [][32]byte{})
|
| 1078 |
+
if err != nil {
|
| 1079 |
+
panic(err)
|
| 1080 |
+
}
|
| 1081 |
+
testState = state.NewState(stateCfg, pgstatestorage.NewPostgresStorage(cfg, stateDb), executorClient, stateTree, nil, mt)
|
| 1082 |
+
|
| 1083 |
+
dbTx, err := testState.BeginStateTransaction(ctx)
|
| 1084 |
+
require.NoError(t, err)
|
| 1085 |
+
err = testState.AddBlock(ctx, block, dbTx)
|
| 1086 |
+
assert.NoError(t, err)
|
| 1087 |
+
|
| 1088 |
+
batchNumber := uint64(1)
|
| 1089 |
+
_, err = testState.Exec(ctx, "INSERT INTO state.batch (batch_num, wip) VALUES ($1, FALSE)", batchNumber)
|
| 1090 |
+
assert.NoError(t, err)
|
| 1091 |
+
|
| 1092 |
+
time := time.Now()
|
| 1093 |
+
blockNumber := big.NewInt(1)
|
| 1094 |
+
|
| 1095 |
+
maxBlocks := 3
|
| 1096 |
+
txsPerBlock := 4
|
| 1097 |
+
logsPerTx := 5
|
| 1098 |
+
|
| 1099 |
+
nonce := uint64(0)
|
| 1100 |
+
|
| 1101 |
+
// number of blocks to be created
|
| 1102 |
+
for b := 0; b < maxBlocks; b++ {
|
| 1103 |
+
logIndex := uint(0)
|
| 1104 |
+
transactions := make([]*types.Transaction, 0, txsPerBlock)
|
| 1105 |
+
receipts := make([]*types.Receipt, 0, txsPerBlock)
|
| 1106 |
+
stateRoots := make([]common.Hash, 0, txsPerBlock)
|
| 1107 |
+
|
| 1108 |
+
// number of transactions in a block to be created
|
| 1109 |
+
for t := 0; t < txsPerBlock; t++ {
|
| 1110 |
+
nonce++
|
| 1111 |
+
txIndex := uint(t + 1)
|
| 1112 |
+
|
| 1113 |
+
tx := types.NewTx(&types.LegacyTx{
|
| 1114 |
+
Nonce: nonce,
|
| 1115 |
+
To: nil,
|
| 1116 |
+
Value: new(big.Int),
|
| 1117 |
+
Gas: 0,
|
| 1118 |
+
GasPrice: big.NewInt(0),
|
| 1119 |
+
})
|
| 1120 |
+
|
| 1121 |
+
logs := []*types.Log{}
|
| 1122 |
+
|
| 1123 |
+
// if block is even logIndex follows a sequence related to the block
|
| 1124 |
+
// for odd blocks logIndex follows a sequence related ot the tx
|
| 1125 |
+
// this is needed to simulate a logIndex difference introduced on Etrog
|
| 1126 |
+
// and we need to maintain to be able to synchronize these blocks
|
| 1127 |
+
// number of logs in a transaction to be created
|
| 1128 |
+
for l := 0; l < logsPerTx; l++ {
|
| 1129 |
+
li := logIndex
|
| 1130 |
+
if b%2 != 0 { // even block
|
| 1131 |
+
li = uint(l)
|
| 1132 |
+
}
|
| 1133 |
+
|
| 1134 |
+
logs = append(logs, &types.Log{TxHash: tx.Hash(), TxIndex: txIndex, Index: li})
|
| 1135 |
+
logIndex++
|
| 1136 |
+
}
|
| 1137 |
+
|
| 1138 |
+
receipt := &types.Receipt{
|
| 1139 |
+
Type: tx.Type(),
|
| 1140 |
+
PostState: state.ZeroHash.Bytes(),
|
| 1141 |
+
CumulativeGasUsed: 0,
|
| 1142 |
+
EffectiveGasPrice: big.NewInt(0),
|
| 1143 |
+
BlockNumber: blockNumber,
|
| 1144 |
+
GasUsed: tx.Gas(),
|
| 1145 |
+
TxHash: tx.Hash(),
|
| 1146 |
+
TransactionIndex: txIndex,
|
| 1147 |
+
Status: types.ReceiptStatusSuccessful,
|
| 1148 |
+
Logs: logs,
|
| 1149 |
+
}
|
| 1150 |
+
|
| 1151 |
+
transactions = append(transactions, tx)
|
| 1152 |
+
receipts = append(receipts, receipt)
|
| 1153 |
+
stateRoots = append(stateRoots, state.ZeroHash)
|
| 1154 |
+
}
|
| 1155 |
+
|
| 1156 |
+
header := state.NewL2Header(&types.Header{
|
| 1157 |
+
Number: big.NewInt(int64(b) + 1),
|
| 1158 |
+
ParentHash: state.ZeroHash,
|
| 1159 |
+
Coinbase: state.ZeroAddress,
|
| 1160 |
+
Root: state.ZeroHash,
|
| 1161 |
+
GasUsed: 1,
|
| 1162 |
+
GasLimit: 10,
|
| 1163 |
+
Time: uint64(time.Unix()),
|
| 1164 |
+
})
|
| 1165 |
+
|
| 1166 |
+
st := trie.NewStackTrie(nil)
|
| 1167 |
+
l2Block := state.NewL2Block(header, transactions, []*state.L2Header{}, receipts, st)
|
| 1168 |
+
for _, receipt := range receipts {
|
| 1169 |
+
receipt.BlockHash = l2Block.Hash()
|
| 1170 |
+
}
|
| 1171 |
+
|
| 1172 |
+
numTxs := len(transactions)
|
| 1173 |
+
storeTxsEGPData := make([]state.StoreTxEGPData, numTxs)
|
| 1174 |
+
txsL2Hash := make([]common.Hash, numTxs)
|
| 1175 |
+
for i := range transactions {
|
| 1176 |
+
storeTxsEGPData[i] = state.StoreTxEGPData{EGPLog: nil, EffectivePercentage: state.MaxEffectivePercentage}
|
| 1177 |
+
txsL2Hash[i] = common.HexToHash(fmt.Sprintf("0x%d", i))
|
| 1178 |
+
}
|
| 1179 |
+
|
| 1180 |
+
err = testState.AddL2Block(ctx, batchNumber, l2Block, receipts, txsL2Hash, storeTxsEGPData, stateRoots, dbTx)
|
| 1181 |
+
require.NoError(t, err)
|
| 1182 |
+
}
|
| 1183 |
+
|
| 1184 |
require.NoError(t, dbTx.Commit(ctx))
|
| 1185 |
+
|
| 1186 |
+
type testCase struct {
|
| 1187 |
+
name string
|
| 1188 |
+
blockNumber uint64
|
| 1189 |
+
logCount int
|
| 1190 |
+
expectedError error
|
| 1191 |
+
}
|
| 1192 |
+
|
| 1193 |
+
testCases := []testCase{
|
| 1194 |
+
{
|
| 1195 |
+
name: "logs returned successfully",
|
| 1196 |
+
blockNumber: 1,
|
| 1197 |
+
logCount: 20,
|
| 1198 |
+
expectedError: nil,
|
| 1199 |
+
},
|
| 1200 |
+
{
|
| 1201 |
+
name: "logs returned successfully",
|
| 1202 |
+
blockNumber: 2,
|
| 1203 |
+
logCount: 20,
|
| 1204 |
+
expectedError: nil,
|
| 1205 |
+
},
|
| 1206 |
+
}
|
| 1207 |
+
|
| 1208 |
+
for _, testCase := range testCases {
|
| 1209 |
+
t.Run(testCase.name, func(t *testing.T) {
|
| 1210 |
+
logs, err := testState.GetLogsByBlockNumber(ctx, testCase.blockNumber, nil)
|
| 1211 |
+
assert.Equal(t, testCase.logCount, len(logs))
|
| 1212 |
+
assert.Equal(t, testCase.expectedError, err)
|
| 1213 |
+
|
| 1214 |
+
// check tx index and log index order
|
| 1215 |
+
lastBlockNumber := uint64(0)
|
| 1216 |
+
lastTxIndex := uint(0)
|
| 1217 |
+
lastLogIndex := uint(0)
|
| 1218 |
+
|
| 1219 |
+
for i, l := range logs {
|
| 1220 |
+
// if block has changed and it's not the first log, reset lastTxIndex
|
| 1221 |
+
if uint(l.BlockNumber) != uint(lastBlockNumber) && i != 0 {
|
| 1222 |
+
lastTxIndex = 0
|
| 1223 |
+
}
|
| 1224 |
+
|
| 1225 |
+
if l.TxIndex < lastTxIndex {
|
| 1226 |
+
t.Errorf("invalid tx index, expected greater than or equal to %v, but found %v", lastTxIndex, l.TxIndex)
|
| 1227 |
+
}
|
| 1228 |
+
// add tolerance for log index Etrog issue that was starting log indexes from 0 for each tx within a block
|
| 1229 |
+
// if tx index has changed and the log index starts on zero, than resets the lastLogIndex to zero
|
| 1230 |
+
if l.TxIndex != lastTxIndex && l.Index == 0 {
|
| 1231 |
+
lastLogIndex = 0
|
| 1232 |
+
}
|
| 1233 |
+
|
| 1234 |
+
if l.Index < lastLogIndex {
|
| 1235 |
+
t.Errorf("invalid log index, expected greater than %v, but found %v", lastLogIndex, l.Index)
|
| 1236 |
+
}
|
| 1237 |
+
|
| 1238 |
+
lastBlockNumber = l.BlockNumber
|
| 1239 |
+
lastTxIndex = l.TxIndex
|
| 1240 |
+
lastLogIndex = l.Index
|
| 1241 |
+
}
|
| 1242 |
+
})
|
| 1243 |
+
}
|
| 1244 |
}
|
| 1245 |
|
| 1246 |
func TestGetNativeBlockHashesInRange(t *testing.T) {
|
|
|
|
| 1371 |
require.NoError(t, dbTx.Commit(ctx))
|
| 1372 |
}
|
| 1373 |
|
| 1374 |
+
func TestGetBatchL2DataByNumber(t *testing.T) {
|
| 1375 |
+
// Init database instance
|
| 1376 |
+
initOrResetDB()
|
| 1377 |
+
ctx := context.Background()
|
| 1378 |
+
tx, err := testState.BeginStateTransaction(ctx)
|
| 1379 |
+
require.NoError(t, err)
|
| 1380 |
+
defer func() { require.NoError(t, tx.Commit(ctx)) }()
|
| 1381 |
+
|
| 1382 |
+
// empty case
|
| 1383 |
+
var batchNum uint64 = 4
|
| 1384 |
+
const (
|
| 1385 |
+
openBatchSQL = "INSERT INTO state.batch (batch_num, raw_txs_data, wip) VALUES ($1, $2, false)"
|
| 1386 |
+
resetBatchesSQL = "DELETE FROM state.batch"
|
| 1387 |
+
)
|
| 1388 |
+
_, err = tx.Exec(ctx, openBatchSQL, batchNum, nil)
|
| 1389 |
+
require.NoError(t, err)
|
| 1390 |
+
data, err := testState.GetBatchL2DataByNumber(ctx, batchNum, tx)
|
| 1391 |
+
require.NoError(t, err)
|
| 1392 |
+
assert.Nil(t, data)
|
| 1393 |
+
|
| 1394 |
+
// not empty case
|
| 1395 |
+
expectedData := []byte("foo bar")
|
| 1396 |
+
batchNum = 5
|
| 1397 |
+
_, err = tx.Exec(ctx, openBatchSQL, batchNum, expectedData)
|
| 1398 |
+
require.NoError(t, err)
|
| 1399 |
+
actualData, err := testState.GetBatchL2DataByNumber(ctx, batchNum, tx)
|
| 1400 |
+
require.NoError(t, err)
|
| 1401 |
+
assert.Equal(t, expectedData, actualData)
|
| 1402 |
+
|
| 1403 |
+
multiGet := []uint64{uint64(4), uint64(5), uint64(6)}
|
| 1404 |
+
allData, err := testState.GetBatchL2DataByNumbers(ctx, multiGet, tx)
|
| 1405 |
+
require.NoError(t, err)
|
| 1406 |
+
require.Equal(t, expectedData, allData[uint64(5)])
|
| 1407 |
+
|
| 1408 |
+
// Force backup
|
| 1409 |
+
_, err = tx.Exec(ctx, resetBatchesSQL)
|
| 1410 |
+
require.NoError(t, err)
|
| 1411 |
+
|
| 1412 |
+
// Get batch 4 from backup
|
| 1413 |
+
batchNum = 4
|
| 1414 |
+
data, err = testState.GetBatchL2DataByNumber(ctx, batchNum, tx)
|
| 1415 |
+
require.NoError(t, err)
|
| 1416 |
+
assert.Nil(t, data)
|
| 1417 |
+
|
| 1418 |
+
// Get batch 5 from backup
|
| 1419 |
+
batchNum = 5
|
| 1420 |
+
actualData, err = testState.GetBatchL2DataByNumber(ctx, batchNum, tx)
|
| 1421 |
+
require.NoError(t, err)
|
| 1422 |
+
assert.Equal(t, expectedData, actualData)
|
| 1423 |
+
|
| 1424 |
+
// Update batch 5 and get it from backup
|
| 1425 |
+
expectedData = []byte("new foo bar")
|
| 1426 |
+
_, err = tx.Exec(ctx, openBatchSQL, batchNum, expectedData)
|
| 1427 |
+
require.NoError(t, err)
|
| 1428 |
+
_, err = tx.Exec(ctx, resetBatchesSQL)
|
| 1429 |
+
require.NoError(t, err)
|
| 1430 |
+
actualData, err = testState.GetBatchL2DataByNumber(ctx, batchNum, tx)
|
| 1431 |
+
require.NoError(t, err)
|
| 1432 |
+
assert.Equal(t, expectedData, actualData)
|
| 1433 |
+
}
|
| 1434 |
+
|
| 1435 |
+
func TestGetBatchL2DataByNumbers(t *testing.T) {
|
| 1436 |
+
initOrResetDB()
|
| 1437 |
+
ctx := context.Background()
|
| 1438 |
+
tx, err := testState.BeginStateTransaction(ctx)
|
| 1439 |
+
require.NoError(t, err)
|
| 1440 |
+
defer func() { require.NoError(t, tx.Commit(ctx)) }()
|
| 1441 |
+
|
| 1442 |
+
var i1, i2, i3, i4, i5 = uint64(1), uint64(2), uint64(3), uint64(4), uint64(5)
|
| 1443 |
+
var d1, d2, d4 = []byte("foobar"), []byte("dingbat"), []byte{0xb}
|
| 1444 |
+
|
| 1445 |
+
const insertBatch = "INSERT INTO state.batch (batch_num, raw_txs_data) VALUES ($1, $2)"
|
| 1446 |
+
_, err = tx.Exec(ctx, insertBatch, i1, d1)
|
| 1447 |
+
require.NoError(t, err)
|
| 1448 |
+
_, err = tx.Exec(ctx, insertBatch, i2, d2)
|
| 1449 |
+
require.NoError(t, err)
|
| 1450 |
+
_, err = tx.Exec(ctx, insertBatch, i3, nil)
|
| 1451 |
+
require.NoError(t, err)
|
| 1452 |
+
|
| 1453 |
+
// Add a forced batch too, needs a block
|
| 1454 |
+
block1 := *block
|
| 1455 |
+
block1.BlockNumber = 1000
|
| 1456 |
+
err = testState.AddBlock(ctx, &block1, tx)
|
| 1457 |
+
require.NoError(t, err)
|
| 1458 |
+
err = tx.Commit(ctx)
|
| 1459 |
+
require.NoError(t, err)
|
| 1460 |
+
|
| 1461 |
+
tx, err = testState.BeginStateTransaction(ctx)
|
| 1462 |
+
require.NoError(t, err)
|
| 1463 |
+
|
| 1464 |
+
const insertForcedBatch = "INSERT INTO state.forced_batch (forced_batch_num, timestamp, raw_txs_data, block_num) VALUES (4, now(),'0b', 1000)"
|
| 1465 |
+
_, err = testState.Exec(ctx, insertForcedBatch)
|
| 1466 |
+
require.NoError(t, err)
|
| 1467 |
+
|
| 1468 |
+
allData, err := testState.GetForcedBatchDataByNumbers(ctx, []uint64{i4}, tx)
|
| 1469 |
+
require.NoError(t, err)
|
| 1470 |
+
assert.Equal(t, d4, allData[i4])
|
| 1471 |
+
|
| 1472 |
+
_, ok := allData[i5]
|
| 1473 |
+
assert.False(t, ok)
|
| 1474 |
+
}
|
| 1475 |
+
|
| 1476 |
func createL1InfoTreeExitRootStorageEntryForTest(blockNumber uint64, index uint32) *state.L1InfoTreeExitRootStorageEntry {
|
| 1477 |
exitRoot := state.L1InfoTreeExitRootStorageEntry{
|
| 1478 |
L1InfoTreeLeaf: state.L1InfoTreeLeaf{
|
|
|
|
| 1674 |
require.Equal(t, uint64(2002), fb.BlockNumber)
|
| 1675 |
require.Equal(t, "0x717e05de47a87a7d1679e183f1c224150675f6302b7da4eaab526b2b91ae0761", fb.GlobalExitRoot.String())
|
| 1676 |
require.Equal(t, []byte{0xb}, fb.RawTxsData)
|
| 1677 |
+
|
| 1678 |
+
// also check data retrieval
|
| 1679 |
+
fbData, err := testState.GetForcedBatchDataByNumbers(ctx, []uint64{1}, dbTx)
|
| 1680 |
+
require.NoError(t, err)
|
| 1681 |
+
var expected = make(map[uint64][]byte)
|
| 1682 |
+
expected[uint64(1)] = []byte{0xb}
|
| 1683 |
+
require.Equal(t, expected, fbData)
|
| 1684 |
}
|
| 1685 |
|
| 1686 |
func TestGetLastGER(t *testing.T) {
|
|
|
|
| 1757 |
ger, err = testState.GetLatestBatchGlobalExitRoot(ctx, dbTx)
|
| 1758 |
require.NoError(t, err)
|
| 1759 |
require.Equal(t, common.HexToHash("0x2").String(), ger.String())
|
| 1760 |
+
}
|
| 1761 |
+
|
| 1762 |
+
func TestGetFirstUncheckedBlock(t *testing.T) {
|
| 1763 |
+
var err error
|
| 1764 |
+
blockNumber := uint64(51001)
|
| 1765 |
+
err = testState.AddBlock(context.Background(), &state.Block{BlockNumber: blockNumber, Checked: true}, nil)
|
| 1766 |
+
require.NoError(t, err)
|
| 1767 |
+
err = testState.AddBlock(context.Background(), &state.Block{BlockNumber: blockNumber + 1, Checked: false}, nil)
|
| 1768 |
+
require.NoError(t, err)
|
| 1769 |
+
err = testState.AddBlock(context.Background(), &state.Block{BlockNumber: blockNumber + 2, Checked: true}, nil)
|
| 1770 |
+
require.NoError(t, err)
|
| 1771 |
+
|
| 1772 |
+
block, err := testState.GetFirstUncheckedBlock(context.Background(), blockNumber, nil)
|
| 1773 |
+
require.NoError(t, err)
|
| 1774 |
+
require.Equal(t, uint64(blockNumber+1), block.BlockNumber)
|
| 1775 |
+
}
|
| 1776 |
+
|
| 1777 |
+
func TestUpdateCheckedBlockByNumber(t *testing.T) {
|
| 1778 |
+
var err error
|
| 1779 |
+
blockNumber := uint64(54001)
|
| 1780 |
+
err = testState.AddBlock(context.Background(), &state.Block{BlockNumber: blockNumber, Checked: true}, nil)
|
| 1781 |
+
require.NoError(t, err)
|
| 1782 |
+
err = testState.AddBlock(context.Background(), &state.Block{BlockNumber: blockNumber + 1, Checked: false}, nil)
|
| 1783 |
+
require.NoError(t, err)
|
| 1784 |
+
err = testState.AddBlock(context.Background(), &state.Block{BlockNumber: blockNumber + 2, Checked: true}, nil)
|
| 1785 |
+
require.NoError(t, err)
|
| 1786 |
+
|
| 1787 |
+
b1, err := testState.GetBlockByNumber(context.Background(), uint64(blockNumber), nil)
|
| 1788 |
+
require.NoError(t, err)
|
| 1789 |
+
require.True(t, b1.Checked)
|
| 1790 |
+
|
| 1791 |
+
err = testState.UpdateCheckedBlockByNumber(context.Background(), uint64(blockNumber), false, nil)
|
| 1792 |
+
require.NoError(t, err)
|
| 1793 |
+
|
| 1794 |
+
b1, err = testState.GetBlockByNumber(context.Background(), uint64(blockNumber), nil)
|
| 1795 |
+
require.NoError(t, err)
|
| 1796 |
+
require.False(t, b1.Checked)
|
| 1797 |
+
}
|
| 1798 |
|
| 1799 |
+
func TestGetFirstUncheckedBlock(t *testing.T) {
|
| 1800 |
+
var err error
|
| 1801 |
+
blockNumber := uint64(51001)
|
| 1802 |
+
err = testState.AddBlock(context.Background(), &state.Block{BlockNumber: blockNumber, Checked: true}, nil)
|
| 1803 |
+
require.NoError(t, err)
|
| 1804 |
+
err = testState.AddBlock(context.Background(), &state.Block{BlockNumber: blockNumber + 1, Checked: false}, nil)
|
| 1805 |
+
require.NoError(t, err)
|
| 1806 |
+
err = testState.AddBlock(context.Background(), &state.Block{BlockNumber: blockNumber + 2, Checked: true}, nil)
|
| 1807 |
+
require.NoError(t, err)
|
| 1808 |
+
|
| 1809 |
+
block, err := testState.GetFirstUncheckedBlock(context.Background(), blockNumber, nil)
|
| 1810 |
+
require.NoError(t, err)
|
| 1811 |
+
require.Equal(t, uint64(blockNumber+1), block.BlockNumber)
|
| 1812 |
+
}
|
| 1813 |
+
|
| 1814 |
+
func TestUpdateCheckedBlockByNumber(t *testing.T) {
|
| 1815 |
+
var err error
|
| 1816 |
+
blockNumber := uint64(54001)
|
| 1817 |
+
err = testState.AddBlock(context.Background(), &state.Block{BlockNumber: blockNumber, Checked: true}, nil)
|
| 1818 |
+
require.NoError(t, err)
|
| 1819 |
+
err = testState.AddBlock(context.Background(), &state.Block{BlockNumber: blockNumber + 1, Checked: false}, nil)
|
| 1820 |
+
require.NoError(t, err)
|
| 1821 |
+
err = testState.AddBlock(context.Background(), &state.Block{BlockNumber: blockNumber + 2, Checked: true}, nil)
|
| 1822 |
+
require.NoError(t, err)
|
| 1823 |
+
|
| 1824 |
+
b1, err := testState.GetBlockByNumber(context.Background(), uint64(blockNumber), nil)
|
| 1825 |
+
require.NoError(t, err)
|
| 1826 |
+
require.True(t, b1.Checked)
|
| 1827 |
+
|
| 1828 |
+
err = testState.UpdateCheckedBlockByNumber(context.Background(), uint64(blockNumber), false, nil)
|
| 1829 |
+
require.NoError(t, err)
|
| 1830 |
+
|
| 1831 |
+
b1, err = testState.GetBlockByNumber(context.Background(), uint64(blockNumber), nil)
|
| 1832 |
+
require.NoError(t, err)
|
| 1833 |
+
require.False(t, b1.Checked)
|
| 1834 |
+
}
|
| 1835 |
+
|
| 1836 |
+
func TestGetUncheckedBlocks(t *testing.T) {
|
| 1837 |
+
var err error
|
| 1838 |
+
blockNumber := uint64(61001)
|
| 1839 |
+
err = testState.AddBlock(context.Background(), &state.Block{BlockNumber: blockNumber, Checked: true}, nil)
|
| 1840 |
+
require.NoError(t, err)
|
| 1841 |
+
err = testState.AddBlock(context.Background(), &state.Block{BlockNumber: blockNumber + 1, Checked: false}, nil)
|
| 1842 |
+
require.NoError(t, err)
|
| 1843 |
+
err = testState.AddBlock(context.Background(), &state.Block{BlockNumber: blockNumber + 2, Checked: true}, nil)
|
| 1844 |
+
require.NoError(t, err)
|
| 1845 |
+
err = testState.AddBlock(context.Background(), &state.Block{BlockNumber: blockNumber + 3, Checked: false}, nil)
|
| 1846 |
+
require.NoError(t, err)
|
| 1847 |
+
err = testState.AddBlock(context.Background(), &state.Block{BlockNumber: blockNumber + 4, Checked: false}, nil)
|
| 1848 |
+
require.NoError(t, err)
|
| 1849 |
+
|
| 1850 |
+
blocks, err := testState.GetUncheckedBlocks(context.Background(), blockNumber, blockNumber+3, nil)
|
| 1851 |
+
require.NoError(t, err)
|
| 1852 |
+
require.Equal(t, 2, len(blocks))
|
| 1853 |
+
require.Equal(t, uint64(blockNumber+1), blocks[0].BlockNumber)
|
| 1854 |
+
require.Equal(t, uint64(blockNumber+3), blocks[1].BlockNumber)
|
| 1855 |
}
|
|
@@ -13,12 +14,19 @@
|
|
| 13 |
// - VerifiedBatches
|
| 14 |
// - Entries in exit_root table
|
| 15 |
err := s.ResetToL1BlockNumber(ctx, blockNumber, dbTx)
|
| 16 |
-
if err
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
// is going to be a commit or a rollback. So is going to be rebuild on the next
|
| 20 |
-
// request that needs it.
|
| 21 |
-
s.l1InfoTree = nil
|
| 22 |
}
|
| 23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
}
|
|
|
|
| 14 |
// - VerifiedBatches
|
| 15 |
// - Entries in exit_root table
|
| 16 |
err := s.ResetToL1BlockNumber(ctx, blockNumber, dbTx)
|
| 17 |
+
if err != nil {
|
| 18 |
+
log.Error("error resetting L1BlockNumber. Error: ", err)
|
| 19 |
+
return err
|
|
|
|
|
|
|
|
|
|
| 20 |
}
|
| 21 |
+
s.ResetL1InfoTree()
|
| 22 |
+
return nil
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
// ResetL1InfoTree resets the L1InfoTree
|
| 26 |
+
func (s *State) ResetL1InfoTree() {
|
| 27 |
+
// Discard L1InfoTree cache
|
| 28 |
+
// We can't rebuild cache, because we are inside a transaction, so we dont known
|
| 29 |
+
// is going to be a commit or a rollback. So is going to be rebuild on the next
|
| 30 |
+
// request that needs it.
|
| 31 |
+
s.l1InfoTree = nil
|
| 32 |
}
|
|
@@ -10,6 +10,13 @@
|
|
| 10 |
"google.golang.org/grpc/credentials/insecure"
|
| 11 |
)
|
| 12 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
// NewExecutorClient is the executor client constructor.
|
| 14 |
func NewExecutorClient(ctx context.Context, c Config) (ExecutorServiceClient, *grpc.ClientConn, context.CancelFunc) {
|
| 15 |
opts := []grpc.DialOption{
|
|
|
|
| 10 |
"google.golang.org/grpc/credentials/insecure"
|
| 11 |
)
|
| 12 |
|
| 13 |
+
const (
|
| 14 |
+
// ExecutionMode0 is the execution mode for the sequencer and RPC, default one
|
| 15 |
+
ExecutionMode0 = uint64(0)
|
| 16 |
+
// ExecutionMode1 is the execution mode for the synchronizer
|
| 17 |
+
ExecutionMode1 = uint64(1)
|
| 18 |
+
)
|
| 19 |
+
|
| 20 |
// NewExecutorClient is the executor client constructor.
|
| 21 |
func NewExecutorClient(ctx context.Context, c Config) (ExecutorServiceClient, *grpc.ClientConn, context.CancelFunc) {
|
| 22 |
opts := []grpc.DialOption{
|
|
@@ -62,13 +62,37 @@
|
|
| 62 |
return state
|
| 63 |
}
|
| 64 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
// BeginStateTransaction starts a state transaction
|
| 66 |
func (s *State) BeginStateTransaction(ctx context.Context) (pgx.Tx, error) {
|
| 67 |
tx, err := s.Begin(ctx)
|
| 68 |
if err != nil {
|
| 69 |
return nil, err
|
| 70 |
}
|
| 71 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 72 |
}
|
| 73 |
|
| 74 |
// GetBalance from a given address
|
|
|
|
| 62 |
return state
|
| 63 |
}
|
| 64 |
|
| 65 |
+
// StateTx is the state transaction that extends the database tx
|
| 66 |
+
type StateTx struct {
|
| 67 |
+
pgx.Tx
|
| 68 |
+
stateInstance *State
|
| 69 |
+
L1InfoTreeModified bool
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
// BeginStateTransaction starts a state transaction
|
| 73 |
func (s *State) BeginStateTransaction(ctx context.Context) (pgx.Tx, error) {
|
| 74 |
tx, err := s.Begin(ctx)
|
| 75 |
if err != nil {
|
| 76 |
return nil, err
|
| 77 |
}
|
| 78 |
+
res := &StateTx{
|
| 79 |
+
Tx: tx,
|
| 80 |
+
stateInstance: s,
|
| 81 |
+
}
|
| 82 |
+
return res, nil
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
// Rollback do the dbTx rollback + modifications in cache mechanism
|
| 86 |
+
func (tx *StateTx) Rollback(ctx context.Context) error {
|
| 87 |
+
if tx.L1InfoTreeModified {
|
| 88 |
+
tx.stateInstance.ResetL1InfoTree()
|
| 89 |
+
}
|
| 90 |
+
return tx.Tx.Rollback(ctx)
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
// SetL1InfoTreeModified sets the flag to true to save that the L1InfoTree has been modified
|
| 94 |
+
func (tx *StateTx) SetL1InfoTreeModified() {
|
| 95 |
+
tx.L1InfoTreeModified = true
|
| 96 |
}
|
| 97 |
|
| 98 |
// GetBalance from a given address
|
|
@@ -78,7 +78,15 @@
|
|
| 78 |
var effectivePercentage []uint8
|
| 79 |
for i := 0; i <= count; i++ {
|
| 80 |
txsToEncode = append(txsToEncode, *l2Block.Transactions()[i])
|
| 81 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 82 |
log.Debugf("trace will reprocess tx: %v", l2Block.Transactions()[i].Hash().String())
|
| 83 |
}
|
| 84 |
|
|
|
|
| 78 |
var effectivePercentage []uint8
|
| 79 |
for i := 0; i <= count; i++ {
|
| 80 |
txsToEncode = append(txsToEncode, *l2Block.Transactions()[i])
|
| 81 |
+
txGasPrice := tx.GasPrice()
|
| 82 |
+
effectiveGasPrice := receipt.EffectiveGasPrice
|
| 83 |
+
egpPercentage, err := CalculateEffectiveGasPricePercentage(txGasPrice, effectiveGasPrice)
|
| 84 |
+
if errors.Is(err, ErrEffectiveGasPriceEmpty) {
|
| 85 |
+
egpPercentage = MaxEffectivePercentage
|
| 86 |
+
} else if err != nil {
|
| 87 |
+
return nil, err
|
| 88 |
+
}
|
| 89 |
+
effectivePercentage = append(effectivePercentage, egpPercentage)
|
| 90 |
log.Debugf("trace will reprocess tx: %v", l2Block.Transactions()[i].Hash().String())
|
| 91 |
}
|
| 92 |
|
|
@@ -141,7 +141,7 @@
|
|
| 141 |
}
|
| 142 |
|
| 143 |
// firstTxToInsert := len(existingTxs)
|
| 144 |
-
|
| 145 |
for i := 0; i < len(processedTxs); i++ {
|
| 146 |
processedTx := processedTxs[i]
|
| 147 |
// if the transaction has an intrinsic invalid tx error it means
|
|
@@ -169,7 +169,7 @@
|
|
| 169 |
header.BlockInfoRoot = processedBlock.BlockInfoRoot
|
| 170 |
transactions := []*types.Transaction{&processedTx.Tx}
|
| 171 |
|
| 172 |
-
receipt := GenerateReceipt(header.Number, processedTx, uint(
|
| 173 |
if !CheckLogOrder(receipt.Logs) {
|
| 174 |
return fmt.Errorf("error: logs received from executor are not in order")
|
| 175 |
}
|
|
@@ -193,6 +193,7 @@
|
|
| 193 |
if err := s.AddL2Block(ctx, batchNumber, l2Block, receipts, txsL2Hash, storeTxsEGPData, imStateRoots, dbTx); err != nil {
|
| 194 |
return err
|
| 195 |
}
|
|
|
|
| 196 |
}
|
| 197 |
}
|
| 198 |
return nil
|
|
@@ -509,8 +510,7 @@
|
|
| 509 |
}
|
| 510 |
nonce := loadedNonce.Uint64()
|
| 511 |
|
| 512 |
-
|
| 513 |
-
transactions := s.BuildChangeL2Block(deltaTimestamp, uint32(0))
|
| 514 |
|
| 515 |
batchL2Data, err := EncodeUnsignedTransaction(*tx, s.cfg.ChainID, &nonce, forkID)
|
| 516 |
if err != nil {
|
|
@@ -535,22 +535,24 @@
|
|
| 535 |
|
| 536 |
// v2 fields
|
| 537 |
L1InfoRoot: l2Block.BlockInfoRoot().Bytes(),
|
| 538 |
-
TimestampLimit:
|
| 539 |
SkipFirstChangeL2Block: cFalse,
|
| 540 |
SkipWriteBlockInfoRoot: cTrue,
|
|
|
|
| 541 |
}
|
| 542 |
if noZKEVMCounters {
|
| 543 |
processBatchRequestV2.NoCounters = cTrue
|
| 544 |
}
|
| 545 |
|
| 546 |
-
log.Debugf("internalProcessUnsignedTransactionV2[processBatchRequestV2.From]: %v", processBatchRequestV2.From)
|
| 547 |
log.Debugf("internalProcessUnsignedTransactionV2[processBatchRequestV2.OldBatchNum]: %v", processBatchRequestV2.OldBatchNum)
|
| 548 |
log.Debugf("internalProcessUnsignedTransactionV2[processBatchRequestV2.OldStateRoot]: %v", hex.EncodeToHex(processBatchRequestV2.OldStateRoot))
|
| 549 |
log.Debugf("internalProcessUnsignedTransactionV2[processBatchRequestV2.OldAccInputHash]: %v", hex.EncodeToHex(processBatchRequestV2.OldAccInputHash))
|
|
|
|
| 550 |
log.Debugf("internalProcessUnsignedTransactionV2[processBatchRequestV2.Coinbase]: %v", processBatchRequestV2.Coinbase)
|
| 551 |
-
log.Debugf("internalProcessUnsignedTransactionV2[processBatchRequestV2.ForkId]: %v", processBatchRequestV2.ForkId)
|
| 552 |
-
log.Debugf("internalProcessUnsignedTransactionV2[processBatchRequestV2.ChainId]: %v", processBatchRequestV2.ChainId)
|
| 553 |
log.Debugf("internalProcessUnsignedTransactionV2[processBatchRequestV2.UpdateMerkleTree]: %v", processBatchRequestV2.UpdateMerkleTree)
|
|
|
|
|
|
|
|
|
|
| 554 |
log.Debugf("internalProcessUnsignedTransactionV2[processBatchRequestV2.ContextId]: %v", processBatchRequestV2.ContextId)
|
| 555 |
|
| 556 |
log.Debugf("internalProcessUnsignedTransactionV2[processBatchRequestV2.L1InfoRoot]: %v", hex.EncodeToHex(processBatchRequestV2.L1InfoRoot))
|
|
@@ -1015,6 +1017,7 @@
|
|
| 1015 |
TimestampLimit: uint64(time.Now().Unix()),
|
| 1016 |
SkipFirstChangeL2Block: cTrue,
|
| 1017 |
SkipWriteBlockInfoRoot: cTrue,
|
|
|
|
| 1018 |
}
|
| 1019 |
|
| 1020 |
log.Debugf("EstimateGas[processBatchRequestV2.From]: %v", processBatchRequestV2.From)
|
|
|
|
| 141 |
}
|
| 142 |
|
| 143 |
// firstTxToInsert := len(existingTxs)
|
| 144 |
+
txIndex := 0
|
| 145 |
for i := 0; i < len(processedTxs); i++ {
|
| 146 |
processedTx := processedTxs[i]
|
| 147 |
// if the transaction has an intrinsic invalid tx error it means
|
|
|
|
| 169 |
header.BlockInfoRoot = processedBlock.BlockInfoRoot
|
| 170 |
transactions := []*types.Transaction{&processedTx.Tx}
|
| 171 |
|
| 172 |
+
receipt := GenerateReceipt(header.Number, processedTx, uint(txIndex), forkID)
|
| 173 |
if !CheckLogOrder(receipt.Logs) {
|
| 174 |
return fmt.Errorf("error: logs received from executor are not in order")
|
| 175 |
}
|
|
|
|
| 193 |
if err := s.AddL2Block(ctx, batchNumber, l2Block, receipts, txsL2Hash, storeTxsEGPData, imStateRoots, dbTx); err != nil {
|
| 194 |
return err
|
| 195 |
}
|
| 196 |
+
txIndex++
|
| 197 |
}
|
| 198 |
}
|
| 199 |
return nil
|
|
|
|
| 510 |
}
|
| 511 |
nonce := loadedNonce.Uint64()
|
| 512 |
|
| 513 |
+
transactions := s.BuildChangeL2Block(uint32(0), uint32(0))
|
|
|
|
| 514 |
|
| 515 |
batchL2Data, err := EncodeUnsignedTransaction(*tx, s.cfg.ChainID, &nonce, forkID)
|
| 516 |
if err != nil {
|
|
|
|
| 535 |
|
| 536 |
// v2 fields
|
| 537 |
L1InfoRoot: l2Block.BlockInfoRoot().Bytes(),
|
| 538 |
+
TimestampLimit: l2Block.Time(),
|
| 539 |
SkipFirstChangeL2Block: cFalse,
|
| 540 |
SkipWriteBlockInfoRoot: cTrue,
|
| 541 |
+
ExecutionMode: executor.ExecutionMode0,
|
| 542 |
}
|
| 543 |
if noZKEVMCounters {
|
| 544 |
processBatchRequestV2.NoCounters = cTrue
|
| 545 |
}
|
| 546 |
|
|
|
|
| 547 |
log.Debugf("internalProcessUnsignedTransactionV2[processBatchRequestV2.OldBatchNum]: %v", processBatchRequestV2.OldBatchNum)
|
| 548 |
log.Debugf("internalProcessUnsignedTransactionV2[processBatchRequestV2.OldStateRoot]: %v", hex.EncodeToHex(processBatchRequestV2.OldStateRoot))
|
| 549 |
log.Debugf("internalProcessUnsignedTransactionV2[processBatchRequestV2.OldAccInputHash]: %v", hex.EncodeToHex(processBatchRequestV2.OldAccInputHash))
|
| 550 |
+
|
| 551 |
log.Debugf("internalProcessUnsignedTransactionV2[processBatchRequestV2.Coinbase]: %v", processBatchRequestV2.Coinbase)
|
|
|
|
|
|
|
| 552 |
log.Debugf("internalProcessUnsignedTransactionV2[processBatchRequestV2.UpdateMerkleTree]: %v", processBatchRequestV2.UpdateMerkleTree)
|
| 553 |
+
log.Debugf("internalProcessUnsignedTransactionV2[processBatchRequestV2.ChainId]: %v", processBatchRequestV2.ChainId)
|
| 554 |
+
log.Debugf("internalProcessUnsignedTransactionV2[processBatchRequestV2.ForkId]: %v", processBatchRequestV2.ForkId)
|
| 555 |
+
log.Debugf("internalProcessUnsignedTransactionV2[processBatchRequestV2.From]: %v", processBatchRequestV2.From)
|
| 556 |
log.Debugf("internalProcessUnsignedTransactionV2[processBatchRequestV2.ContextId]: %v", processBatchRequestV2.ContextId)
|
| 557 |
|
| 558 |
log.Debugf("internalProcessUnsignedTransactionV2[processBatchRequestV2.L1InfoRoot]: %v", hex.EncodeToHex(processBatchRequestV2.L1InfoRoot))
|
|
|
|
| 1017 |
TimestampLimit: uint64(time.Now().Unix()),
|
| 1018 |
SkipFirstChangeL2Block: cTrue,
|
| 1019 |
SkipWriteBlockInfoRoot: cTrue,
|
| 1020 |
+
ExecutionMode: executor.ExecutionMode0,
|
| 1021 |
}
|
| 1022 |
|
| 1023 |
log.Debugf("EstimateGas[processBatchRequestV2.From]: %v", processBatchRequestV2.From)
|
|
@@ -6,9 +6,9 @@
|
|
| 6 |
"fmt"
|
| 7 |
"math/big"
|
| 8 |
|
| 9 |
-
"github.com/0xPolygonHermez/zkevm-node/jsonrpc/types"
|
| 10 |
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 11 |
"github.com/0xPolygonHermez/zkevm-node/state"
|
|
|
|
| 12 |
"github.com/jackc/pgx/v4"
|
| 13 |
)
|
| 14 |
|
|
@@ -36,13 +36,16 @@
|
|
| 36 |
func NewCheckL2BlockHash(state stateGetL2Block,
|
| 37 |
trustedClient trustedRPCGetL2Block,
|
| 38 |
initialL2BlockNumber uint64,
|
| 39 |
-
modulusBlockNumber uint64) *CheckL2BlockHash {
|
|
|
|
|
|
|
|
|
|
| 40 |
return &CheckL2BlockHash{
|
| 41 |
state: state,
|
| 42 |
trustedClient: trustedClient,
|
| 43 |
lastL2BlockChecked: initialL2BlockNumber,
|
| 44 |
modulusL2BlockToCheck: modulusBlockNumber,
|
| 45 |
-
}
|
| 46 |
}
|
| 47 |
|
| 48 |
// CheckL2Block checks the L2Block hash between the local and the trusted
|
|
@@ -74,6 +77,9 @@
|
|
| 74 |
log.Infof("checkL2block: skip check L2block (next to check: %d) currently LastL2BlockNumber: %d", minL2BlockNumberToCheck, lastLocalL2BlockNumber)
|
| 75 |
return false, 0
|
| 76 |
}
|
|
|
|
|
|
|
|
|
|
| 77 |
return true, l2BlockNumber
|
| 78 |
}
|
| 79 |
|
|
@@ -129,11 +135,14 @@
|
|
| 129 |
}
|
| 130 |
|
| 131 |
func compareL2Blocks(prefixLogs string, localL2Block *state.L2Block, trustedL2Block *types.Block) error {
|
| 132 |
-
if localL2Block == nil || trustedL2Block == nil
|
| 133 |
-
return fmt.Errorf("%s localL2Block or trustedL2Block
|
|
|
|
|
|
|
|
|
|
| 134 |
}
|
| 135 |
-
if localL2Block.
|
| 136 |
-
return fmt.Errorf("%s localL2Block.
|
| 137 |
}
|
| 138 |
return nil
|
| 139 |
}
|
|
|
|
| 6 |
"fmt"
|
| 7 |
"math/big"
|
| 8 |
|
|
|
|
| 9 |
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 10 |
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 11 |
+
"github.com/ethereum/go-ethereum/core/types"
|
| 12 |
"github.com/jackc/pgx/v4"
|
| 13 |
)
|
| 14 |
|
|
|
|
| 36 |
func NewCheckL2BlockHash(state stateGetL2Block,
|
| 37 |
trustedClient trustedRPCGetL2Block,
|
| 38 |
initialL2BlockNumber uint64,
|
| 39 |
+
modulusBlockNumber uint64) (*CheckL2BlockHash, error) {
|
| 40 |
+
if modulusBlockNumber == 0 {
|
| 41 |
+
return nil, fmt.Errorf("error: modulusBlockNumber is zero")
|
| 42 |
+
}
|
| 43 |
return &CheckL2BlockHash{
|
| 44 |
state: state,
|
| 45 |
trustedClient: trustedClient,
|
| 46 |
lastL2BlockChecked: initialL2BlockNumber,
|
| 47 |
modulusL2BlockToCheck: modulusBlockNumber,
|
| 48 |
+
}, nil
|
| 49 |
}
|
| 50 |
|
| 51 |
// CheckL2Block checks the L2Block hash between the local and the trusted
|
|
|
|
| 77 |
log.Infof("checkL2block: skip check L2block (next to check: %d) currently LastL2BlockNumber: %d", minL2BlockNumberToCheck, lastLocalL2BlockNumber)
|
| 78 |
return false, 0
|
| 79 |
}
|
| 80 |
+
if l2BlockNumber%p.modulusL2BlockToCheck != 0 {
|
| 81 |
+
return false, 0
|
| 82 |
+
}
|
| 83 |
return true, l2BlockNumber
|
| 84 |
}
|
| 85 |
|
|
|
|
| 135 |
}
|
| 136 |
|
| 137 |
func compareL2Blocks(prefixLogs string, localL2Block *state.L2Block, trustedL2Block *types.Block) error {
|
| 138 |
+
if localL2Block == nil || trustedL2Block == nil {
|
| 139 |
+
return fmt.Errorf("%s localL2Block or trustedL2Block are nil", prefixLogs)
|
| 140 |
+
}
|
| 141 |
+
if localL2Block.Hash() != trustedL2Block.Hash() {
|
| 142 |
+
return fmt.Errorf("%s localL2Block.Hash %s and trustedL2Block.Hash %s are different", prefixLogs, localL2Block.Hash().String(), trustedL2Block.Hash().String())
|
| 143 |
}
|
| 144 |
+
if localL2Block.ParentHash() != trustedL2Block.ParentHash() {
|
| 145 |
+
return fmt.Errorf("%s localL2Block.ParentHash %s and trustedL2Block.ParentHash %s are different", prefixLogs, localL2Block.ParentHash().String(), trustedL2Block.ParentHash().String())
|
| 146 |
}
|
| 147 |
return nil
|
| 148 |
}
|
|
@@ -19,7 +18,7 @@
|
|
| 19 |
type CheckL2BlocksTestData struct {
|
| 20 |
sut *actions.CheckL2BlockHash
|
| 21 |
mockState *mock_syncinterfaces.StateFullInterface
|
| 22 |
-
zKEVMClient *mock_syncinterfaces.
|
| 23 |
}
|
| 24 |
|
| 25 |
func TestCheckL2BlockHash_GetMinimumL2BlockToCheck(t *testing.T) {
|
|
@@ -33,12 +32,15 @@
|
|
| 33 |
{1, 10, 10},
|
| 34 |
{9, 10, 10},
|
| 35 |
{10, 10, 20},
|
| 36 |
-
{0,
|
| 37 |
-
{1,
|
| 38 |
}
|
|
|
|
|
|
|
| 39 |
for _, data := range values {
|
| 40 |
// Call the GetNextL2BlockToCheck method
|
| 41 |
-
checkL2Block := actions.NewCheckL2BlockHash(nil, nil, data.initial, data.modulus)
|
|
|
|
| 42 |
nextL2Block := checkL2Block.GetMinimumL2BlockToCheck()
|
| 43 |
|
| 44 |
// Assert the expected result
|
|
@@ -57,9 +59,11 @@
|
|
| 57 |
func newCheckL2BlocksTestData(t *testing.T, initialL2Block, modulus uint64) CheckL2BlocksTestData {
|
| 58 |
res := CheckL2BlocksTestData{
|
| 59 |
mockState: mock_syncinterfaces.NewStateFullInterface(t),
|
| 60 |
-
zKEVMClient: mock_syncinterfaces.
|
| 61 |
}
|
| 62 |
-
|
|
|
|
|
|
|
| 63 |
return res
|
| 64 |
}
|
| 65 |
func TestCheckL2BlockHash_GetNextL2BlockToCheck(t *testing.T) {
|
|
@@ -78,7 +82,8 @@
|
|
| 78 |
}
|
| 79 |
|
| 80 |
for _, data := range values {
|
| 81 |
-
checkL2Block := actions.NewCheckL2BlockHash(nil, nil, 0,
|
|
|
|
| 82 |
shouldCheck, nextL2Block := checkL2Block.GetNextL2BlockToCheck(data.lastLocalL2BlockNumber, data.minL2BlockNumberToCheck)
|
| 83 |
|
| 84 |
assert.Equal(t, data.expectedShouldCheck, shouldCheck, data)
|
|
@@ -87,7 +92,7 @@
|
|
| 87 |
}
|
| 88 |
|
| 89 |
func TestCheckL2BlockHashMatch(t *testing.T) {
|
| 90 |
-
data := newCheckL2BlocksTestData(t, 1,
|
| 91 |
lastL2Block := uint64(14)
|
| 92 |
lastL2BlockBigInt := big.NewInt(int64(lastL2Block))
|
| 93 |
gethHeader := types.Header{
|
|
@@ -97,19 +102,24 @@
|
|
| 97 |
|
| 98 |
data.mockState.EXPECT().GetLastL2BlockNumber(mock.Anything, mock.Anything).Return(lastL2Block, nil)
|
| 99 |
data.mockState.EXPECT().GetL2BlockByNumber(mock.Anything, lastL2Block, mock.Anything).Return(stateBlock, nil)
|
| 100 |
-
l2blockHash := stateBlock.Hash()
|
| 101 |
-
rpcL2Block := rpctypes.Block{
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
}
|
|
|
|
| 105 |
|
| 106 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 107 |
err := data.sut.CheckL2Block(context.Background(), nil)
|
| 108 |
require.NoError(t, err)
|
| 109 |
}
|
| 110 |
|
| 111 |
-
func
|
| 112 |
-
data := newCheckL2BlocksTestData(t, 1,
|
| 113 |
lastL2Block := uint64(14)
|
| 114 |
lastL2BlockBigInt := big.NewInt(int64(lastL2Block))
|
| 115 |
gethHeader := types.Header{
|
|
@@ -119,13 +129,14 @@
|
|
| 119 |
|
| 120 |
data.mockState.EXPECT().GetLastL2BlockNumber(mock.Anything, mock.Anything).Return(lastL2Block, nil)
|
| 121 |
data.mockState.EXPECT().GetL2BlockByNumber(mock.Anything, lastL2Block, mock.Anything).Return(stateBlock, nil)
|
| 122 |
-
l2blockHash := common.HexToHash("0x1234")
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
Number:
|
| 126 |
-
|
|
|
|
| 127 |
|
| 128 |
-
data.zKEVMClient.EXPECT().BlockByNumber(mock.Anything, lastL2BlockBigInt).Return(
|
| 129 |
err := data.sut.CheckL2Block(context.Background(), nil)
|
| 130 |
require.Error(t, err)
|
| 131 |
}
|
|
|
|
| 18 |
type CheckL2BlocksTestData struct {
|
| 19 |
sut *actions.CheckL2BlockHash
|
| 20 |
mockState *mock_syncinterfaces.StateFullInterface
|
| 21 |
+
zKEVMClient *mock_syncinterfaces.ZKEVMClientEthereumCompatibleInterface
|
| 22 |
}
|
| 23 |
|
| 24 |
func TestCheckL2BlockHash_GetMinimumL2BlockToCheck(t *testing.T) {
|
|
|
|
| 32 |
{1, 10, 10},
|
| 33 |
{9, 10, 10},
|
| 34 |
{10, 10, 20},
|
| 35 |
+
{0, 1, 1},
|
| 36 |
+
{1, 1, 2},
|
| 37 |
}
|
| 38 |
+
_, err := actions.NewCheckL2BlockHash(nil, nil, 1, 0)
|
| 39 |
+
require.Error(t, err)
|
| 40 |
for _, data := range values {
|
| 41 |
// Call the GetNextL2BlockToCheck method
|
| 42 |
+
checkL2Block, err := actions.NewCheckL2BlockHash(nil, nil, data.initial, data.modulus)
|
| 43 |
+
require.NoError(t, err)
|
| 44 |
nextL2Block := checkL2Block.GetMinimumL2BlockToCheck()
|
| 45 |
|
| 46 |
// Assert the expected result
|
|
|
|
| 59 |
func newCheckL2BlocksTestData(t *testing.T, initialL2Block, modulus uint64) CheckL2BlocksTestData {
|
| 60 |
res := CheckL2BlocksTestData{
|
| 61 |
mockState: mock_syncinterfaces.NewStateFullInterface(t),
|
| 62 |
+
zKEVMClient: mock_syncinterfaces.NewZKEVMClientEthereumCompatibleInterface(t),
|
| 63 |
}
|
| 64 |
+
var err error
|
| 65 |
+
res.sut, err = actions.NewCheckL2BlockHash(res.mockState, res.zKEVMClient, initialL2Block, modulus)
|
| 66 |
+
require.NoError(t, err)
|
| 67 |
return res
|
| 68 |
}
|
| 69 |
func TestCheckL2BlockHash_GetNextL2BlockToCheck(t *testing.T) {
|
|
|
|
| 82 |
}
|
| 83 |
|
| 84 |
for _, data := range values {
|
| 85 |
+
checkL2Block, err := actions.NewCheckL2BlockHash(nil, nil, 0, 1)
|
| 86 |
+
require.NoError(t, err)
|
| 87 |
shouldCheck, nextL2Block := checkL2Block.GetNextL2BlockToCheck(data.lastLocalL2BlockNumber, data.minL2BlockNumberToCheck)
|
| 88 |
|
| 89 |
assert.Equal(t, data.expectedShouldCheck, shouldCheck, data)
|
|
|
|
| 92 |
}
|
| 93 |
|
| 94 |
func TestCheckL2BlockHashMatch(t *testing.T) {
|
| 95 |
+
data := newCheckL2BlocksTestData(t, 1, 14)
|
| 96 |
lastL2Block := uint64(14)
|
| 97 |
lastL2BlockBigInt := big.NewInt(int64(lastL2Block))
|
| 98 |
gethHeader := types.Header{
|
|
|
|
| 102 |
|
| 103 |
data.mockState.EXPECT().GetLastL2BlockNumber(mock.Anything, mock.Anything).Return(lastL2Block, nil)
|
| 104 |
data.mockState.EXPECT().GetL2BlockByNumber(mock.Anything, lastL2Block, mock.Anything).Return(stateBlock, nil)
|
| 105 |
+
//l2blockHash := stateBlock.Hash()
|
| 106 |
+
// rpcL2Block := rpctypes.Block{
|
| 107 |
+
// Hash: &l2blockHash,
|
| 108 |
+
// Number: rpctypes.ArgUint64(lastL2Block),
|
| 109 |
+
// }
|
| 110 |
+
// create a types.Block object
|
| 111 |
|
| 112 |
+
rpcL2Block := types.NewBlock(&types.Header{
|
| 113 |
+
Number: big.NewInt(int64(lastL2Block)),
|
| 114 |
+
}, nil, nil, nil, nil)
|
| 115 |
+
|
| 116 |
+
data.zKEVMClient.EXPECT().BlockByNumber(mock.Anything, lastL2BlockBigInt).Return(rpcL2Block, nil)
|
| 117 |
err := data.sut.CheckL2Block(context.Background(), nil)
|
| 118 |
require.NoError(t, err)
|
| 119 |
}
|
| 120 |
|
| 121 |
+
func TestCheckL2BlockHashMismatch(t *testing.T) {
|
| 122 |
+
data := newCheckL2BlocksTestData(t, 1, 14)
|
| 123 |
lastL2Block := uint64(14)
|
| 124 |
lastL2BlockBigInt := big.NewInt(int64(lastL2Block))
|
| 125 |
gethHeader := types.Header{
|
|
|
|
| 129 |
|
| 130 |
data.mockState.EXPECT().GetLastL2BlockNumber(mock.Anything, mock.Anything).Return(lastL2Block, nil)
|
| 131 |
data.mockState.EXPECT().GetL2BlockByNumber(mock.Anything, lastL2Block, mock.Anything).Return(stateBlock, nil)
|
| 132 |
+
//l2blockHash := common.HexToHash("0x1234")
|
| 133 |
+
|
| 134 |
+
rpcL2Block := types.NewBlock(&types.Header{
|
| 135 |
+
Number: big.NewInt(int64(lastL2Block)),
|
| 136 |
+
ParentHash: common.HexToHash("0x1234"),
|
| 137 |
+
}, nil, nil, nil, nil)
|
| 138 |
|
| 139 |
+
data.zKEVMClient.EXPECT().BlockByNumber(mock.Anything, lastL2BlockBigInt).Return(rpcL2Block, nil)
|
| 140 |
err := data.sut.CheckL2Block(context.Background(), nil)
|
| 141 |
require.Error(t, err)
|
| 142 |
}
|
|
@@ -3,7 +3,6 @@
|
|
| 3 |
import (
|
| 4 |
"context"
|
| 5 |
"errors"
|
| 6 |
-
"fmt"
|
| 7 |
"time"
|
| 8 |
|
| 9 |
"github.com/0xPolygonHermez/zkevm-node/etherman"
|
|
@@ -60,58 +59,12 @@
|
|
| 60 |
|
| 61 |
sbatch := l1Block.SequencedBatches[order.Pos][0]
|
| 62 |
|
|
|
|
| 63 |
if sbatch.SequencedBatchElderberryData == nil {
|
| 64 |
-
log.
|
| 65 |
-
|
|
|
|
| 66 |
}
|
| 67 |
-
// We need to check that the sequence match
|
| 68 |
-
err := g.sanityCheckExpectedSequence(sbatch.SequencedBatchElderberryData.InitSequencedBatchNumber, dbTx)
|
| 69 |
-
if err != nil {
|
| 70 |
-
return err
|
| 71 |
-
}
|
| 72 |
-
// We known that the MaxSequenceTimestamp is the same for all the batches so we can use the first one
|
| 73 |
-
err = g.previousProcessor.ProcessSequenceBatches(ctx, l1Block.SequencedBatches[order.Pos], l1Block.BlockNumber, time.Unix(int64(sbatch.SequencedBatchElderberryData.MaxSequenceTimestamp), 0), dbTx)
|
| 74 |
-
// The last L2block timestamp must match MaxSequenceTimestamp
|
| 75 |
-
if err != nil {
|
| 76 |
-
return err
|
| 77 |
-
}
|
| 78 |
-
// It checks the timestamp of the last L2 block, but it's just log an error instead of refusing the event
|
| 79 |
-
_ = g.sanityCheckTstampLastL2Block(sbatch.SequencedBatchElderberryData.MaxSequenceTimestamp, dbTx)
|
| 80 |
-
return nil
|
| 81 |
-
}
|
| 82 |
-
|
| 83 |
-
func (g *ProcessorL1SequenceBatchesElderberry) sanityCheckExpectedSequence(initialBatchNumber uint64, dbTx pgx.Tx) error {
|
| 84 |
-
// We need to check that the sequence match
|
| 85 |
-
lastVirtualBatchNum, err := g.state.GetLastVirtualBatchNum(context.Background(), dbTx)
|
| 86 |
-
if err != nil {
|
| 87 |
-
log.Errorf("Error getting last virtual batch number: %s", err)
|
| 88 |
-
return err
|
| 89 |
-
}
|
| 90 |
-
if lastVirtualBatchNum != initialBatchNumber {
|
| 91 |
-
log.Errorf("The last virtual batch number is not the expected one. Expected: %d (last on DB), got: %d (L1 event)", lastVirtualBatchNum+1, initialBatchNumber)
|
| 92 |
-
return fmt.Errorf("the last virtual batch number is not the expected one. Expected: %d (last on DB), got: %d (L1 event) err:%w", lastVirtualBatchNum+1, initialBatchNumber, ErrInvalidInitialBatchNumber)
|
| 93 |
-
}
|
| 94 |
-
return nil
|
| 95 |
-
}
|
| 96 |
|
| 97 |
-
|
| 98 |
-
lastVirtualBatchNum, err := g.state.GetLastVirtualBatchNum(context.Background(), dbTx)
|
| 99 |
-
if err != nil {
|
| 100 |
-
log.Errorf("Error getting last virtual batch number: %s", err)
|
| 101 |
-
return err
|
| 102 |
-
}
|
| 103 |
-
lastL2Block, err := g.state.GetLastL2BlockByBatchNumber(context.Background(), lastVirtualBatchNum, dbTx)
|
| 104 |
-
if err != nil {
|
| 105 |
-
log.Errorf("Error getting last virtual batch number: %s", err)
|
| 106 |
-
return err
|
| 107 |
-
}
|
| 108 |
-
if lastL2Block == nil {
|
| 109 |
-
//TODO: find the previous batch until we find a L2 block to check the timestamp
|
| 110 |
-
return nil
|
| 111 |
-
}
|
| 112 |
-
if uint64(lastL2Block.ReceivedAt.Unix()) > timeLimit {
|
| 113 |
-
log.Errorf("The last L2 block timestamp can't be greater than timeLimit. Expected: %d (L1 event), got: %d (last L2Block)", timeLimit, lastL2Block.ReceivedAt.Unix())
|
| 114 |
-
return fmt.Errorf("wrong timestamp of last L2 block timestamp with L1 event timestamp")
|
| 115 |
-
}
|
| 116 |
-
return nil
|
| 117 |
}
|
|
|
|
| 3 |
import (
|
| 4 |
"context"
|
| 5 |
"errors"
|
|
|
|
| 6 |
"time"
|
| 7 |
|
| 8 |
"github.com/0xPolygonHermez/zkevm-node/etherman"
|
|
|
|
| 59 |
|
| 60 |
sbatch := l1Block.SequencedBatches[order.Pos][0]
|
| 61 |
|
| 62 |
+
executionTime := l1Block.ReceivedAt
|
| 63 |
if sbatch.SequencedBatchElderberryData == nil {
|
| 64 |
+
log.Warnf("No elderberry sequenced batch data for batch %d", sbatch.BatchNumber)
|
| 65 |
+
} else {
|
| 66 |
+
executionTime = time.Unix(int64(sbatch.SequencedBatchElderberryData.MaxSequenceTimestamp), 0)
|
| 67 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
|
| 69 |
+
return g.previousProcessor.ProcessSequenceBatches(ctx, l1Block.SequencedBatches[order.Pos], l1Block.BlockNumber, executionTime, dbTx)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 70 |
}
|
|
@@ -391,7 +391,7 @@
|
|
| 391 |
reason := reorgReasons.String()
|
| 392 |
|
| 393 |
if p.sync.IsTrustedSequencer() {
|
| 394 |
-
log.Errorf("TRUSTED REORG DETECTED! Batch: %d
|
| 395 |
// Halt function never have to return! it must blocks the process
|
| 396 |
p.halt(ctx, fmt.Errorf("TRUSTED REORG DETECTED! Batch: %d", batch.BatchNumber))
|
| 397 |
log.Errorf("CRITICAL!!!: Never have to execute this code. Halt function never have to return! it must blocks the process")
|
|
|
|
| 391 |
reason := reorgReasons.String()
|
| 392 |
|
| 393 |
if p.sync.IsTrustedSequencer() {
|
| 394 |
+
log.Errorf("TRUSTED REORG DETECTED! Batch: %d reason:%s", batch.BatchNumber, reason)
|
| 395 |
// Halt function never have to return! it must blocks the process
|
| 396 |
p.halt(ctx, fmt.Errorf("TRUSTED REORG DETECTED! Batch: %d", batch.BatchNumber))
|
| 397 |
log.Errorf("CRITICAL!!!: Never have to execute this code. Halt function never have to return! it must blocks the process")
|
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package common
|
| 2 |
+
|
| 3 |
+
import "fmt"
|
| 4 |
+
|
| 5 |
+
// ReorgError is an error that is raised when a reorg is detected
|
| 6 |
+
type ReorgError struct {
|
| 7 |
+
// BlockNumber is the block number that caused the reorg
|
| 8 |
+
BlockNumber uint64
|
| 9 |
+
Err error
|
| 10 |
+
}
|
| 11 |
+
|
| 12 |
+
// NewReorgError creates a new ReorgError
|
| 13 |
+
func NewReorgError(blockNumber uint64, err error) *ReorgError {
|
| 14 |
+
return &ReorgError{
|
| 15 |
+
BlockNumber: blockNumber,
|
| 16 |
+
Err: err,
|
| 17 |
+
}
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
func (e *ReorgError) Error() string {
|
| 21 |
+
return fmt.Sprintf("%s blockNumber: %d", e.Err.Error(), e.BlockNumber)
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
// IsReorgError checks if an error is a ReorgError
|
| 25 |
+
func IsReorgError(err error) bool {
|
| 26 |
+
_, ok := err.(*ReorgError)
|
| 27 |
+
return ok
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
// GetReorgErrorBlockNumber returns the block number that caused the reorg
|
| 31 |
+
func GetReorgErrorBlockNumber(err error) uint64 {
|
| 32 |
+
if reorgErr, ok := err.(*ReorgError); ok {
|
| 33 |
+
return reorgErr.BlockNumber
|
| 34 |
+
}
|
| 35 |
+
return 0
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
// GetReorgError returns the error that caused the reorg
|
| 39 |
+
func GetReorgError(err error) error {
|
| 40 |
+
if reorgErr, ok := err.(*ReorgError); ok {
|
| 41 |
+
return reorgErr.Err
|
| 42 |
+
}
|
| 43 |
+
return nil
|
| 44 |
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package syncinterfaces
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"context"
|
| 5 |
+
"fmt"
|
| 6 |
+
|
| 7 |
+
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 8 |
+
)
|
| 9 |
+
|
| 10 |
+
type IterationResult struct {
|
| 11 |
+
Err error
|
| 12 |
+
ReorgDetected bool
|
| 13 |
+
BlockNumber uint64
|
| 14 |
+
ReorgMessage string
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
func (ir *IterationResult) String() string {
|
| 18 |
+
if ir.Err == nil {
|
| 19 |
+
if ir.ReorgDetected {
|
| 20 |
+
return fmt.Sprintf("IterationResult{ReorgDetected: %v, BlockNumber: %d ReorgMessage:%s}", ir.ReorgDetected, ir.BlockNumber, ir.ReorgMessage)
|
| 21 |
+
} else {
|
| 22 |
+
return "IterationResult{None}"
|
| 23 |
+
}
|
| 24 |
+
} else {
|
| 25 |
+
return fmt.Sprintf("IterationResult{Err: %s, ReorgDetected: %v, BlockNumber: %d ReorgMessage:%s}", ir.Err.Error(), ir.ReorgDetected, ir.BlockNumber, ir.ReorgMessage)
|
| 26 |
+
}
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
type AsyncL1BlockChecker interface {
|
| 30 |
+
Run(ctx context.Context, onFinish func())
|
| 31 |
+
RunSynchronous(ctx context.Context) IterationResult
|
| 32 |
+
Stop()
|
| 33 |
+
GetResult() *IterationResult
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
type L1BlockCheckerIntegrator interface {
|
| 37 |
+
OnStart(ctx context.Context) error
|
| 38 |
+
OnResetState(ctx context.Context)
|
| 39 |
+
CheckReorgWrapper(ctx context.Context, reorgFirstBlockOk *state.Block, errReportedByReorgFunc error) (*state.Block, error)
|
| 40 |
+
}
|
|
@@ -14,10 +14,12 @@
|
|
| 14 |
HeaderByNumber(ctx context.Context, number *big.Int) (*ethTypes.Header, error)
|
| 15 |
GetRollupInfoByBlockRange(ctx context.Context, fromBlock uint64, toBlock *uint64) ([]etherman.Block, map[common.Hash][]etherman.Order, error)
|
| 16 |
EthBlockByNumber(ctx context.Context, blockNumber uint64) (*ethTypes.Block, error)
|
| 17 |
-
GetLatestBatchNumber() (uint64, error)
|
| 18 |
GetTrustedSequencerURL() (string, error)
|
| 19 |
VerifyGenBlockNumber(ctx context.Context, genBlockNumber uint64) (bool, error)
|
| 20 |
GetLatestVerifiedBatchNum() (uint64, error)
|
|
|
|
|
|
|
|
|
|
| 21 |
}
|
| 22 |
|
| 23 |
type EthermanGetLatestBatchNumber interface {
|
|
|
|
| 14 |
HeaderByNumber(ctx context.Context, number *big.Int) (*ethTypes.Header, error)
|
| 15 |
GetRollupInfoByBlockRange(ctx context.Context, fromBlock uint64, toBlock *uint64) ([]etherman.Block, map[common.Hash][]etherman.Order, error)
|
| 16 |
EthBlockByNumber(ctx context.Context, blockNumber uint64) (*ethTypes.Block, error)
|
|
|
|
| 17 |
GetTrustedSequencerURL() (string, error)
|
| 18 |
VerifyGenBlockNumber(ctx context.Context, genBlockNumber uint64) (bool, error)
|
| 19 |
GetLatestVerifiedBatchNum() (uint64, error)
|
| 20 |
+
|
| 21 |
+
EthermanGetLatestBatchNumber
|
| 22 |
+
GetFinalizedBlockNumber(ctx context.Context) (uint64, error)
|
| 23 |
}
|
| 24 |
|
| 25 |
type EthermanGetLatestBatchNumber interface {
|
|
@@ -28,7 +28,10 @@
|
|
| 28 |
AddForcedBatch(ctx context.Context, forcedBatch *state.ForcedBatch, dbTx pgx.Tx) error
|
| 29 |
AddBlock(ctx context.Context, block *state.Block, dbTx pgx.Tx) error
|
| 30 |
Reset(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) error
|
|
|
|
| 31 |
GetPreviousBlock(ctx context.Context, offset uint64, dbTx pgx.Tx) (*state.Block, error)
|
|
|
|
|
|
|
| 32 |
GetLastBatchNumber(ctx context.Context, dbTx pgx.Tx) (uint64, error)
|
| 33 |
GetBatchByNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.Batch, error)
|
| 34 |
ResetTrustedState(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) error
|
|
@@ -73,4 +76,6 @@
|
|
| 73 |
UpdateForkIDBlockNumber(ctx context.Context, forkdID uint64, newBlockNumber uint64, updateMemCache bool, dbTx pgx.Tx) error
|
| 74 |
GetLastL2BlockNumber(ctx context.Context, dbTx pgx.Tx) (uint64, error)
|
| 75 |
GetL2BlockByNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (*state.L2Block, error)
|
|
|
|
|
|
|
| 76 |
}
|
|
|
|
| 28 |
AddForcedBatch(ctx context.Context, forcedBatch *state.ForcedBatch, dbTx pgx.Tx) error
|
| 29 |
AddBlock(ctx context.Context, block *state.Block, dbTx pgx.Tx) error
|
| 30 |
Reset(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) error
|
| 31 |
+
GetBlockByNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (*state.Block, error)
|
| 32 |
GetPreviousBlock(ctx context.Context, offset uint64, dbTx pgx.Tx) (*state.Block, error)
|
| 33 |
+
GetFirstUncheckedBlock(ctx context.Context, fromBlockNumber uint64, dbTx pgx.Tx) (*state.Block, error)
|
| 34 |
+
UpdateCheckedBlockByNumber(ctx context.Context, blockNumber uint64, newCheckedStatus bool, dbTx pgx.Tx) error
|
| 35 |
GetLastBatchNumber(ctx context.Context, dbTx pgx.Tx) (uint64, error)
|
| 36 |
GetBatchByNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.Batch, error)
|
| 37 |
ResetTrustedState(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) error
|
|
|
|
| 76 |
UpdateForkIDBlockNumber(ctx context.Context, forkdID uint64, newBlockNumber uint64, updateMemCache bool, dbTx pgx.Tx) error
|
| 77 |
GetLastL2BlockNumber(ctx context.Context, dbTx pgx.Tx) (uint64, error)
|
| 78 |
GetL2BlockByNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (*state.L2Block, error)
|
| 79 |
+
GetUncheckedBlocks(ctx context.Context, fromBlockNumber uint64, toBlockNumber uint64, dbTx pgx.Tx) ([]*state.Block, error)
|
| 80 |
+
GetPreviousBlockToBlockNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (*state.Block, error)
|
| 81 |
}
|
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package syncinterfaces
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"context"
|
| 5 |
+
"math/big"
|
| 6 |
+
|
| 7 |
+
"github.com/ethereum/go-ethereum/core/types"
|
| 8 |
+
)
|
| 9 |
+
|
| 10 |
+
// ZKEVMClientEthereumCompatibleInterface contains the methods required to interact with zkEVM-RPC as a ethereum-API compatible
|
| 11 |
+
//
|
| 12 |
+
// Reason behind: the zkEVMClient have some extensions to ethereum-API that are not compatible with all nodes. So if you need to maximize
|
| 13 |
+
// the compatibility the idea is to use a regular ethereum-API compatible client
|
| 14 |
+
type ZKEVMClientEthereumCompatibleInterface interface {
|
| 15 |
+
ZKEVMClientEthereumCompatibleL2BlockGetter
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
// ZKEVMClientEthereumCompatibleL2BlockGetter contains the methods required to interact with zkEVM-RPC as a ethereum-API compatible for obtain Block information
|
| 19 |
+
type ZKEVMClientEthereumCompatibleL2BlockGetter interface {
|
| 20 |
+
BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error)
|
| 21 |
+
}
|
|
@@ -1,6 +1,8 @@
|
|
| 1 |
package synchronizer
|
| 2 |
|
| 3 |
import (
|
|
|
|
|
|
|
| 4 |
"github.com/0xPolygonHermez/zkevm-node/config/types"
|
| 5 |
"github.com/0xPolygonHermez/zkevm-node/synchronizer/l2_sync"
|
| 6 |
)
|
|
@@ -13,6 +15,8 @@
|
|
| 13 |
SyncChunkSize uint64 `mapstructure:"SyncChunkSize"`
|
| 14 |
// TrustedSequencerURL is the rpc url to connect and sync the trusted state
|
| 15 |
TrustedSequencerURL string `mapstructure:"TrustedSequencerURL"`
|
|
|
|
|
|
|
| 16 |
|
| 17 |
// L1SyncCheckL2BlockHash if is true when a batch is closed is force to check L2Block hash against trustedNode (only apply for permissionless)
|
| 18 |
L1SyncCheckL2BlockHash bool `mapstructure:"L1SyncCheckL2BlockHash"`
|
|
@@ -20,6 +24,7 @@
|
|
| 20 |
// a modules 5, for instance, means check all l2block multiples of 5 (10,15,20,...)
|
| 21 |
L1SyncCheckL2BlockNumberhModulus uint64 `mapstructure:"L1SyncCheckL2BlockNumberhModulus"`
|
| 22 |
|
|
|
|
| 23 |
// L1SynchronizationMode define how to synchronize with L1:
|
| 24 |
// - parallel: Request data to L1 in parallel, and process sequentially. The advantage is that executor is not blocked waiting for L1 data
|
| 25 |
// - sequential: Request data to L1 and execute
|
|
@@ -30,6 +35,35 @@
|
|
| 30 |
L2Synchronization l2_sync.Config `mapstructure:"L2Synchronization"`
|
| 31 |
}
|
| 32 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
// L1ParallelSynchronizationConfig Configuration for parallel mode (if UL1SynchronizationMode equal to 'parallel')
|
| 34 |
type L1ParallelSynchronizationConfig struct {
|
| 35 |
// MaxClients Number of clients used to synchronize with L1
|
|
|
|
| 1 |
package synchronizer
|
| 2 |
|
| 3 |
import (
|
| 4 |
+
"fmt"
|
| 5 |
+
|
| 6 |
"github.com/0xPolygonHermez/zkevm-node/config/types"
|
| 7 |
"github.com/0xPolygonHermez/zkevm-node/synchronizer/l2_sync"
|
| 8 |
)
|
|
|
|
| 15 |
SyncChunkSize uint64 `mapstructure:"SyncChunkSize"`
|
| 16 |
// TrustedSequencerURL is the rpc url to connect and sync the trusted state
|
| 17 |
TrustedSequencerURL string `mapstructure:"TrustedSequencerURL"`
|
| 18 |
+
// SyncBlockProtection specify the state to sync (lastest, finalized or safe)
|
| 19 |
+
SyncBlockProtection string `mapstructure:"SyncBlockProtection"`
|
| 20 |
|
| 21 |
// L1SyncCheckL2BlockHash if is true when a batch is closed is force to check L2Block hash against trustedNode (only apply for permissionless)
|
| 22 |
L1SyncCheckL2BlockHash bool `mapstructure:"L1SyncCheckL2BlockHash"`
|
|
|
|
| 24 |
// a modules 5, for instance, means check all l2block multiples of 5 (10,15,20,...)
|
| 25 |
L1SyncCheckL2BlockNumberhModulus uint64 `mapstructure:"L1SyncCheckL2BlockNumberhModulus"`
|
| 26 |
|
| 27 |
+
L1BlockCheck L1BlockCheckConfig `mapstructure:"L1BlockCheck"`
|
| 28 |
// L1SynchronizationMode define how to synchronize with L1:
|
| 29 |
// - parallel: Request data to L1 in parallel, and process sequentially. The advantage is that executor is not blocked waiting for L1 data
|
| 30 |
// - sequential: Request data to L1 and execute
|
|
|
|
| 35 |
L2Synchronization l2_sync.Config `mapstructure:"L2Synchronization"`
|
| 36 |
}
|
| 37 |
|
| 38 |
+
// L1BlockCheckConfig Configuration for L1 Block Checker
|
| 39 |
+
type L1BlockCheckConfig struct {
|
| 40 |
+
// Enable if is true then the check l1 Block Hash is active
|
| 41 |
+
Enable bool `mapstructure:"Enable"`
|
| 42 |
+
// L1SafeBlockPoint is the point that a block is considered safe enough to be checked
|
| 43 |
+
// it can be: finalized, safe,pending or latest
|
| 44 |
+
L1SafeBlockPoint string `mapstructure:"L1SafeBlockPoint" jsonschema:"enum=finalized,enum=safe, enum=pending,enum=latest"`
|
| 45 |
+
// L1SafeBlockOffset is the offset to add to L1SafeBlockPoint as a safe point
|
| 46 |
+
// it can be positive or negative
|
| 47 |
+
// Example: L1SafeBlockPoint= finalized, L1SafeBlockOffset= -10, then the safe block ten blocks before the finalized block
|
| 48 |
+
L1SafeBlockOffset int `mapstructure:"L1SafeBlockOffset"`
|
| 49 |
+
// ForceCheckBeforeStart if is true then the first time the system is started it will force to check all pending blocks
|
| 50 |
+
ForceCheckBeforeStart bool `mapstructure:"ForceCheckBeforeStart"`
|
| 51 |
+
|
| 52 |
+
// PreCheckEnable if is true then the pre-check is active, will check blocks between L1SafeBlock and L1PreSafeBlock
|
| 53 |
+
PreCheckEnable bool `mapstructure:"PreCheckEnable"`
|
| 54 |
+
// L1PreSafeBlockPoint is the point that a block is considered safe enough to be checked
|
| 55 |
+
// it can be: finalized, safe,pending or latest
|
| 56 |
+
L1PreSafeBlockPoint string `mapstructure:"L1PreSafeBlockPoint" jsonschema:"enum=finalized,enum=safe, enum=pending,enum=latest"`
|
| 57 |
+
// L1PreSafeBlockOffset is the offset to add to L1PreSafeBlockPoint as a safe point
|
| 58 |
+
// it can be positive or negative
|
| 59 |
+
// Example: L1PreSafeBlockPoint= finalized, L1PreSafeBlockOffset= -10, then the safe block ten blocks before the finalized block
|
| 60 |
+
L1PreSafeBlockOffset int `mapstructure:"L1PreSafeBlockOffset"`
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
func (c *L1BlockCheckConfig) String() string {
|
| 64 |
+
return fmt.Sprintf("Enable: %v, L1SafeBlockPoint: %s, L1SafeBlockOffset: %d, ForceCheckBeforeStart: %v", c.Enable, c.L1SafeBlockPoint, c.L1SafeBlockOffset, c.ForceCheckBeforeStart)
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
// L1ParallelSynchronizationConfig Configuration for parallel mode (if UL1SynchronizationMode equal to 'parallel')
|
| 68 |
type L1ParallelSynchronizationConfig struct {
|
| 69 |
// MaxClients Number of clients used to synchronize with L1
|
|
@@ -0,0 +1,183 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package l1_check_block
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"context"
|
| 5 |
+
"sync"
|
| 6 |
+
"time"
|
| 7 |
+
|
| 8 |
+
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 9 |
+
"github.com/0xPolygonHermez/zkevm-node/synchronizer/common"
|
| 10 |
+
"github.com/0xPolygonHermez/zkevm-node/synchronizer/common/syncinterfaces"
|
| 11 |
+
)
|
| 12 |
+
|
| 13 |
+
// L1BlockChecker is an interface that defines the method to check L1 blocks
|
| 14 |
+
type L1BlockChecker interface {
|
| 15 |
+
Step(ctx context.Context) error
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
const (
|
| 19 |
+
defaultPeriodTime = time.Second
|
| 20 |
+
)
|
| 21 |
+
|
| 22 |
+
// AsyncCheck is a wrapper for L1BlockChecker to become asynchronous
|
| 23 |
+
type AsyncCheck struct {
|
| 24 |
+
checker L1BlockChecker
|
| 25 |
+
mutex sync.Mutex
|
| 26 |
+
lastResult *syncinterfaces.IterationResult
|
| 27 |
+
onFinishCall func()
|
| 28 |
+
periodTime time.Duration
|
| 29 |
+
// Wg is a wait group to wait for the result
|
| 30 |
+
Wg sync.WaitGroup
|
| 31 |
+
ctx context.Context
|
| 32 |
+
cancelCtx context.CancelFunc
|
| 33 |
+
isRunning bool
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
// NewAsyncCheck creates a new AsyncCheck
|
| 37 |
+
func NewAsyncCheck(checker L1BlockChecker) *AsyncCheck {
|
| 38 |
+
return &AsyncCheck{
|
| 39 |
+
checker: checker,
|
| 40 |
+
periodTime: defaultPeriodTime,
|
| 41 |
+
}
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
// SetPeriodTime sets the period time between relaunch checker.Step
|
| 45 |
+
func (a *AsyncCheck) SetPeriodTime(periodTime time.Duration) {
|
| 46 |
+
a.periodTime = periodTime
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
// Run is a method that starts the async check
|
| 50 |
+
func (a *AsyncCheck) Run(ctx context.Context, onFinish func()) {
|
| 51 |
+
a.mutex.Lock()
|
| 52 |
+
defer a.mutex.Unlock()
|
| 53 |
+
a.onFinishCall = onFinish
|
| 54 |
+
if a.isRunning {
|
| 55 |
+
log.Infof("%s L1BlockChecker: already running, changing onFinish call", logPrefix)
|
| 56 |
+
return
|
| 57 |
+
}
|
| 58 |
+
a.lastResult = nil
|
| 59 |
+
a.ctx, a.cancelCtx = context.WithCancel(ctx)
|
| 60 |
+
a.launchChecker(a.ctx)
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
// Stop is a method that stops the async check
|
| 64 |
+
func (a *AsyncCheck) Stop() {
|
| 65 |
+
a.cancelCtx()
|
| 66 |
+
a.Wg.Wait()
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
// RunSynchronous is a method that forces the check to be synchronous before starting the async check
|
| 70 |
+
func (a *AsyncCheck) RunSynchronous(ctx context.Context) syncinterfaces.IterationResult {
|
| 71 |
+
return a.executeIteration(ctx)
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
// GetResult returns the last result of the check:
|
| 75 |
+
// - Nil -> still running
|
| 76 |
+
// - Not nil -> finished, and this is the result. You must call again Run to start a new check
|
| 77 |
+
func (a *AsyncCheck) GetResult() *syncinterfaces.IterationResult {
|
| 78 |
+
a.mutex.Lock()
|
| 79 |
+
defer a.mutex.Unlock()
|
| 80 |
+
return a.lastResult
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
// https://stackoverflow.com/questions/32840687/timeout-for-waitgroup-wait
|
| 84 |
+
// waitTimeout waits for the waitgroup for the specified max timeout.
|
| 85 |
+
// Returns true if waiting timed out.
|
| 86 |
+
func waitTimeout(wg *sync.WaitGroup, timeout time.Duration) bool {
|
| 87 |
+
c := make(chan struct{})
|
| 88 |
+
go func() {
|
| 89 |
+
defer close(c)
|
| 90 |
+
wg.Wait()
|
| 91 |
+
}()
|
| 92 |
+
select {
|
| 93 |
+
case <-c:
|
| 94 |
+
return false // completed normally
|
| 95 |
+
case <-time.After(timeout):
|
| 96 |
+
return true // timed out
|
| 97 |
+
}
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
// GetResultBlockingUntilAvailable wait the time specific in timeout, if reach timeout returns current
|
| 101 |
+
// result, if not, wait until the result is available.
|
| 102 |
+
// if timeout is 0, it waits indefinitely
|
| 103 |
+
func (a *AsyncCheck) GetResultBlockingUntilAvailable(timeout time.Duration) *syncinterfaces.IterationResult {
|
| 104 |
+
if timeout == 0 {
|
| 105 |
+
a.Wg.Wait()
|
| 106 |
+
} else {
|
| 107 |
+
waitTimeout(&a.Wg, timeout)
|
| 108 |
+
}
|
| 109 |
+
return a.GetResult()
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
func (a *AsyncCheck) setResult(result syncinterfaces.IterationResult) {
|
| 113 |
+
a.mutex.Lock()
|
| 114 |
+
defer a.mutex.Unlock()
|
| 115 |
+
a.lastResult = &result
|
| 116 |
+
}
|
| 117 |
+
|
| 118 |
+
func (a *AsyncCheck) launchChecker(ctx context.Context) {
|
| 119 |
+
// add waitGroup to wait for a result
|
| 120 |
+
a.Wg.Add(1)
|
| 121 |
+
a.isRunning = true
|
| 122 |
+
go func() {
|
| 123 |
+
log.Infof("%s L1BlockChecker: starting background process", logPrefix)
|
| 124 |
+
for {
|
| 125 |
+
result := a.step(ctx)
|
| 126 |
+
if result != nil {
|
| 127 |
+
a.setResult(*result)
|
| 128 |
+
// Result is set wg is done
|
| 129 |
+
break
|
| 130 |
+
}
|
| 131 |
+
}
|
| 132 |
+
log.Infof("%s L1BlockChecker: finished background process", logPrefix)
|
| 133 |
+
a.Wg.Done()
|
| 134 |
+
a.mutex.Lock()
|
| 135 |
+
onFinishCall := a.onFinishCall
|
| 136 |
+
a.isRunning = false
|
| 137 |
+
a.mutex.Unlock()
|
| 138 |
+
// call onFinish function with no mutex
|
| 139 |
+
if onFinishCall != nil {
|
| 140 |
+
onFinishCall()
|
| 141 |
+
}
|
| 142 |
+
}()
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
// step is a method that executes until executeItertion
|
| 146 |
+
// returns an error or a reorg
|
| 147 |
+
func (a *AsyncCheck) step(ctx context.Context) *syncinterfaces.IterationResult {
|
| 148 |
+
select {
|
| 149 |
+
case <-ctx.Done():
|
| 150 |
+
log.Debugf("%s L1BlockChecker: context done", logPrefix)
|
| 151 |
+
return &syncinterfaces.IterationResult{Err: ctx.Err()}
|
| 152 |
+
default:
|
| 153 |
+
result := a.executeIteration(ctx)
|
| 154 |
+
if result.ReorgDetected {
|
| 155 |
+
return &result
|
| 156 |
+
}
|
| 157 |
+
log.Debugf("%s L1BlockChecker:returned %s waiting %s to relaunch", logPrefix, result.String(), a.periodTime)
|
| 158 |
+
time.Sleep(a.periodTime)
|
| 159 |
+
}
|
| 160 |
+
return nil
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
// executeIteration executes a single iteration of the checker
|
| 164 |
+
func (a *AsyncCheck) executeIteration(ctx context.Context) syncinterfaces.IterationResult {
|
| 165 |
+
res := syncinterfaces.IterationResult{}
|
| 166 |
+
log.Debugf("%s calling checker.Step(...)", logPrefix)
|
| 167 |
+
res.Err = a.checker.Step(ctx)
|
| 168 |
+
log.Debugf("%s returned checker.Step(...) %w", logPrefix, res.Err)
|
| 169 |
+
if res.Err != nil {
|
| 170 |
+
log.Errorf("%s Fail check L1 Blocks: %w", logPrefix, res.Err)
|
| 171 |
+
if common.IsReorgError(res.Err) {
|
| 172 |
+
// log error
|
| 173 |
+
blockNumber := common.GetReorgErrorBlockNumber(res.Err)
|
| 174 |
+
log.Infof("%s Reorg detected at block %d", logPrefix, blockNumber)
|
| 175 |
+
// It keeps blocked until the channel is read
|
| 176 |
+
res.BlockNumber = blockNumber
|
| 177 |
+
res.ReorgDetected = true
|
| 178 |
+
res.ReorgMessage = res.Err.Error()
|
| 179 |
+
res.Err = nil
|
| 180 |
+
}
|
| 181 |
+
}
|
| 182 |
+
return res
|
| 183 |
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package l1_check_block_test
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"context"
|
| 5 |
+
"fmt"
|
| 6 |
+
"sync"
|
| 7 |
+
"testing"
|
| 8 |
+
"time"
|
| 9 |
+
|
| 10 |
+
"github.com/0xPolygonHermez/zkevm-node/synchronizer/common"
|
| 11 |
+
"github.com/0xPolygonHermez/zkevm-node/synchronizer/l1_check_block"
|
| 12 |
+
"github.com/stretchr/testify/require"
|
| 13 |
+
)
|
| 14 |
+
|
| 15 |
+
var (
|
| 16 |
+
errGenericToTestAsync = fmt.Errorf("error_async")
|
| 17 |
+
errReorgToTestAsync = common.NewReorgError(uint64(1234), fmt.Errorf("fake reorg to test"))
|
| 18 |
+
timeoutContextForAsyncTests = time.Second
|
| 19 |
+
)
|
| 20 |
+
|
| 21 |
+
type mockChecker struct {
|
| 22 |
+
Wg *sync.WaitGroup
|
| 23 |
+
ErrorsToReturn []error
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
func (m *mockChecker) Step(ctx context.Context) error {
|
| 27 |
+
defer m.Wg.Done()
|
| 28 |
+
err := m.ErrorsToReturn[0]
|
| 29 |
+
if len(m.ErrorsToReturn) > 0 {
|
| 30 |
+
m.ErrorsToReturn = m.ErrorsToReturn[1:]
|
| 31 |
+
}
|
| 32 |
+
return err
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
// If checker.step() returns ok, the async object will relaunch the call
|
| 36 |
+
func TestAsyncRelaunchCheckerUntilReorgDetected(t *testing.T) {
|
| 37 |
+
mockChecker := &mockChecker{ErrorsToReturn: []error{nil, nil, errGenericToTestAsync, errReorgToTestAsync}, Wg: &sync.WaitGroup{}}
|
| 38 |
+
sut := l1_check_block.NewAsyncCheck(mockChecker)
|
| 39 |
+
sut.SetPeriodTime(0)
|
| 40 |
+
ctx, cancel := context.WithTimeout(context.Background(), timeoutContextForAsyncTests)
|
| 41 |
+
defer cancel()
|
| 42 |
+
mockChecker.Wg.Add(4)
|
| 43 |
+
|
| 44 |
+
sut.Run(ctx, nil)
|
| 45 |
+
|
| 46 |
+
mockChecker.Wg.Wait()
|
| 47 |
+
result := sut.GetResultBlockingUntilAvailable(0)
|
| 48 |
+
require.NotNil(t, result)
|
| 49 |
+
require.Equal(t, uint64(1234), result.BlockNumber)
|
| 50 |
+
require.Equal(t, true, result.ReorgDetected)
|
| 51 |
+
require.Equal(t, nil, result.Err)
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
func TestAsyncGetResultIsNilUntilStops(t *testing.T) {
|
| 55 |
+
mockChecker := &mockChecker{ErrorsToReturn: []error{nil, nil, errGenericToTestAsync, errReorgToTestAsync}, Wg: &sync.WaitGroup{}}
|
| 56 |
+
sut := l1_check_block.NewAsyncCheck(mockChecker)
|
| 57 |
+
sut.SetPeriodTime(0)
|
| 58 |
+
ctx, cancel := context.WithTimeout(context.Background(), timeoutContextForAsyncTests)
|
| 59 |
+
defer cancel()
|
| 60 |
+
mockChecker.Wg.Add(4)
|
| 61 |
+
require.Nil(t, sut.GetResult(), "before start result is Nil")
|
| 62 |
+
|
| 63 |
+
sut.Run(ctx, nil)
|
| 64 |
+
|
| 65 |
+
require.Nil(t, sut.GetResult(), "after start result is Nil")
|
| 66 |
+
mockChecker.Wg.Wait()
|
| 67 |
+
result := sut.GetResultBlockingUntilAvailable(0)
|
| 68 |
+
require.NotNil(t, result)
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
// RunSynchronous it returns the first result, doesnt mind if a reorg or not
|
| 72 |
+
func TestAsyncGRunSynchronousReturnTheFirstResult(t *testing.T) {
|
| 73 |
+
mockChecker := &mockChecker{ErrorsToReturn: []error{errGenericToTestAsync}, Wg: &sync.WaitGroup{}}
|
| 74 |
+
sut := l1_check_block.NewAsyncCheck(mockChecker)
|
| 75 |
+
sut.SetPeriodTime(0)
|
| 76 |
+
ctx, cancel := context.WithTimeout(context.Background(), timeoutContextForAsyncTests)
|
| 77 |
+
defer cancel()
|
| 78 |
+
mockChecker.Wg.Add(1)
|
| 79 |
+
|
| 80 |
+
result := sut.RunSynchronous(ctx)
|
| 81 |
+
|
| 82 |
+
require.NotNil(t, result)
|
| 83 |
+
require.Equal(t, uint64(0), result.BlockNumber)
|
| 84 |
+
require.Equal(t, false, result.ReorgDetected)
|
| 85 |
+
require.Equal(t, errGenericToTestAsync, result.Err)
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
func TestAsyncGRunSynchronousDontAffectGetResult(t *testing.T) {
|
| 89 |
+
mockChecker := &mockChecker{ErrorsToReturn: []error{errGenericToTestAsync}, Wg: &sync.WaitGroup{}}
|
| 90 |
+
sut := l1_check_block.NewAsyncCheck(mockChecker)
|
| 91 |
+
sut.SetPeriodTime(0)
|
| 92 |
+
ctx, cancel := context.WithTimeout(context.Background(), timeoutContextForAsyncTests)
|
| 93 |
+
defer cancel()
|
| 94 |
+
mockChecker.Wg.Add(1)
|
| 95 |
+
|
| 96 |
+
result := sut.RunSynchronous(ctx)
|
| 97 |
+
|
| 98 |
+
require.NotNil(t, result)
|
| 99 |
+
require.Nil(t, sut.GetResult())
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
func TestAsyncStop(t *testing.T) {
|
| 103 |
+
mockChecker := &mockChecker{ErrorsToReturn: []error{nil, nil, errGenericToTestAsync, errReorgToTestAsync}, Wg: &sync.WaitGroup{}}
|
| 104 |
+
sut := l1_check_block.NewAsyncCheck(mockChecker)
|
| 105 |
+
sut.SetPeriodTime(0)
|
| 106 |
+
ctx, cancel := context.WithTimeout(context.Background(), timeoutContextForAsyncTests)
|
| 107 |
+
defer cancel()
|
| 108 |
+
require.Nil(t, sut.GetResult(), "before start result is Nil")
|
| 109 |
+
mockChecker.Wg.Add(4)
|
| 110 |
+
sut.Run(ctx, nil)
|
| 111 |
+
sut.Stop()
|
| 112 |
+
sut.Stop()
|
| 113 |
+
|
| 114 |
+
result := sut.GetResultBlockingUntilAvailable(0)
|
| 115 |
+
require.NotNil(t, result)
|
| 116 |
+
mockChecker.Wg = &sync.WaitGroup{}
|
| 117 |
+
mockChecker.Wg.Add(4)
|
| 118 |
+
mockChecker.ErrorsToReturn = []error{nil, nil, errGenericToTestAsync, errReorgToTestAsync}
|
| 119 |
+
sut.Run(ctx, nil)
|
| 120 |
+
mockChecker.Wg.Wait()
|
| 121 |
+
result = sut.GetResultBlockingUntilAvailable(0)
|
| 122 |
+
require.NotNil(t, result)
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
func TestAsyncMultipleRun(t *testing.T) {
|
| 126 |
+
mockChecker := &mockChecker{ErrorsToReturn: []error{nil, nil, errGenericToTestAsync, errReorgToTestAsync}, Wg: &sync.WaitGroup{}}
|
| 127 |
+
sut := l1_check_block.NewAsyncCheck(mockChecker)
|
| 128 |
+
sut.SetPeriodTime(0)
|
| 129 |
+
ctx, cancel := context.WithTimeout(context.Background(), timeoutContextForAsyncTests)
|
| 130 |
+
defer cancel()
|
| 131 |
+
require.Nil(t, sut.GetResult(), "before start result is Nil")
|
| 132 |
+
mockChecker.Wg.Add(4)
|
| 133 |
+
sut.Run(ctx, nil)
|
| 134 |
+
sut.Run(ctx, nil)
|
| 135 |
+
sut.Run(ctx, nil)
|
| 136 |
+
result := sut.GetResultBlockingUntilAvailable(0)
|
| 137 |
+
require.NotNil(t, result)
|
| 138 |
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package l1_check_block
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"context"
|
| 5 |
+
"errors"
|
| 6 |
+
"fmt"
|
| 7 |
+
"math/big"
|
| 8 |
+
"time"
|
| 9 |
+
|
| 10 |
+
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 11 |
+
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 12 |
+
"github.com/0xPolygonHermez/zkevm-node/synchronizer/common"
|
| 13 |
+
"github.com/ethereum/go-ethereum/core/types"
|
| 14 |
+
"github.com/jackc/pgx/v4"
|
| 15 |
+
)
|
| 16 |
+
|
| 17 |
+
// This object check old L1block to double-check that the L1block hash is correct
|
| 18 |
+
// - Get first not checked block
|
| 19 |
+
// - Get last block on L1 (safe/finalized/ or minus -n)
|
| 20 |
+
|
| 21 |
+
// L1Requester is an interface for GETH client
|
| 22 |
+
type L1Requester interface {
|
| 23 |
+
HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error)
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
// StateInterfacer is an interface for the state
|
| 27 |
+
type StateInterfacer interface {
|
| 28 |
+
GetFirstUncheckedBlock(ctx context.Context, fromBlockNumber uint64, dbTx pgx.Tx) (*state.Block, error)
|
| 29 |
+
UpdateCheckedBlockByNumber(ctx context.Context, blockNumber uint64, newCheckedStatus bool, dbTx pgx.Tx) error
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
// SafeL1BlockNumberFetcher is an interface for fetching the L1 block number reference point (safe, finalized,...)
|
| 33 |
+
type SafeL1BlockNumberFetcher interface {
|
| 34 |
+
GetSafeBlockNumber(ctx context.Context, l1Client L1Requester) (uint64, error)
|
| 35 |
+
Description() string
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
// CheckL1BlockHash is a struct that implements a checker of L1Block hash
|
| 39 |
+
type CheckL1BlockHash struct {
|
| 40 |
+
L1Client L1Requester
|
| 41 |
+
State StateInterfacer
|
| 42 |
+
SafeBlockNumberFetcher SafeL1BlockNumberFetcher
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
// NewCheckL1BlockHash creates a new CheckL1BlockHash
|
| 46 |
+
func NewCheckL1BlockHash(l1Client L1Requester, state StateInterfacer, safeBlockNumberFetcher SafeL1BlockNumberFetcher) *CheckL1BlockHash {
|
| 47 |
+
return &CheckL1BlockHash{
|
| 48 |
+
L1Client: l1Client,
|
| 49 |
+
State: state,
|
| 50 |
+
SafeBlockNumberFetcher: safeBlockNumberFetcher,
|
| 51 |
+
}
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
// Name is a method that returns the name of the checker
|
| 55 |
+
func (p *CheckL1BlockHash) Name() string {
|
| 56 |
+
return logPrefix + " main_checker: "
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
// Step is a method that checks the L1 block hash, run until all blocks are checked and returns
|
| 60 |
+
func (p *CheckL1BlockHash) Step(ctx context.Context) error {
|
| 61 |
+
stateBlock, err := p.State.GetFirstUncheckedBlock(ctx, uint64(0), nil)
|
| 62 |
+
if errors.Is(err, state.ErrNotFound) {
|
| 63 |
+
log.Debugf("%s: No unchecked blocks to check", p.Name())
|
| 64 |
+
return nil
|
| 65 |
+
}
|
| 66 |
+
if err != nil {
|
| 67 |
+
return err
|
| 68 |
+
}
|
| 69 |
+
if stateBlock == nil {
|
| 70 |
+
log.Warnf("%s: function CheckL1Block receive a nil pointer", p.Name())
|
| 71 |
+
return nil
|
| 72 |
+
}
|
| 73 |
+
safeBlockNumber, err := p.SafeBlockNumberFetcher.GetSafeBlockNumber(ctx, p.L1Client)
|
| 74 |
+
if err != nil {
|
| 75 |
+
return err
|
| 76 |
+
}
|
| 77 |
+
log.Debugf("%s: checking from block (%s) %d first block to check: %d....", p.Name(), p.SafeBlockNumberFetcher.Description(), safeBlockNumber, stateBlock.BlockNumber)
|
| 78 |
+
return p.doAllBlocks(ctx, *stateBlock, safeBlockNumber)
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
func (p *CheckL1BlockHash) doAllBlocks(ctx context.Context, firstStateBlock state.Block, safeBlockNumber uint64) error {
|
| 82 |
+
var err error
|
| 83 |
+
startTime := time.Now()
|
| 84 |
+
stateBlock := &firstStateBlock
|
| 85 |
+
numBlocksChecked := 0
|
| 86 |
+
for {
|
| 87 |
+
lastStateBlockNumber := stateBlock.BlockNumber
|
| 88 |
+
if stateBlock.BlockNumber > safeBlockNumber {
|
| 89 |
+
log.Debugf("%s: block %d to check is not still safe enough (%s) %d ", p.Name(), stateBlock.BlockNumber, p.SafeBlockNumberFetcher.Description(), safeBlockNumber, logPrefix)
|
| 90 |
+
return nil
|
| 91 |
+
}
|
| 92 |
+
err = p.doBlock(ctx, stateBlock)
|
| 93 |
+
if err != nil {
|
| 94 |
+
return err
|
| 95 |
+
}
|
| 96 |
+
numBlocksChecked++
|
| 97 |
+
stateBlock, err = p.State.GetFirstUncheckedBlock(ctx, lastStateBlockNumber, nil)
|
| 98 |
+
if errors.Is(err, state.ErrNotFound) {
|
| 99 |
+
diff := time.Since(startTime)
|
| 100 |
+
log.Infof("%s: checked all blocks (%d) (using as safe Block Point(%s): %d) time:%s", p.Name(), numBlocksChecked, p.SafeBlockNumberFetcher.Description(), safeBlockNumber, diff)
|
| 101 |
+
return nil
|
| 102 |
+
}
|
| 103 |
+
}
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
func (p *CheckL1BlockHash) doBlock(ctx context.Context, stateBlock *state.Block) error {
|
| 107 |
+
err := CheckBlockHash(ctx, stateBlock, p.L1Client, p.Name())
|
| 108 |
+
if err != nil {
|
| 109 |
+
return err
|
| 110 |
+
}
|
| 111 |
+
log.Infof("%s: L1Block: %d hash: %s is correct marking as checked", p.Name(), stateBlock.BlockNumber,
|
| 112 |
+
stateBlock.BlockHash.String())
|
| 113 |
+
err = p.State.UpdateCheckedBlockByNumber(ctx, stateBlock.BlockNumber, true, nil)
|
| 114 |
+
if err != nil {
|
| 115 |
+
log.Errorf("%s: Error updating block %d as checked. err: %s", p.Name(), stateBlock.BlockNumber, err.Error())
|
| 116 |
+
return err
|
| 117 |
+
}
|
| 118 |
+
return nil
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
// CheckBlockHash is a method that checks the L1 block hash
|
| 122 |
+
func CheckBlockHash(ctx context.Context, stateBlock *state.Block, L1Client L1Requester, checkerName string) error {
|
| 123 |
+
if stateBlock == nil {
|
| 124 |
+
log.Warn("%s function CheckL1Block receive a nil pointer", checkerName)
|
| 125 |
+
return nil
|
| 126 |
+
}
|
| 127 |
+
l1Block, err := L1Client.HeaderByNumber(ctx, big.NewInt(int64(stateBlock.BlockNumber)))
|
| 128 |
+
if err != nil {
|
| 129 |
+
return err
|
| 130 |
+
}
|
| 131 |
+
if l1Block == nil {
|
| 132 |
+
err = fmt.Errorf("%s request of block: %d to L1 returns a nil", checkerName, stateBlock.BlockNumber)
|
| 133 |
+
log.Error(err.Error())
|
| 134 |
+
return err
|
| 135 |
+
}
|
| 136 |
+
if l1Block.Hash() != stateBlock.BlockHash {
|
| 137 |
+
msg := fmt.Sprintf("%s Reorg detected at block %d l1Block.Hash=%s != stateBlock.Hash=%s. ", checkerName, stateBlock.BlockNumber,
|
| 138 |
+
l1Block.Hash().String(), stateBlock.BlockHash.String())
|
| 139 |
+
if l1Block.ParentHash != stateBlock.ParentHash {
|
| 140 |
+
msg += fmt.Sprintf(" ParentHash are also different. l1Block.ParentHash=%s != stateBlock.ParentHash=%s", l1Block.ParentHash.String(), stateBlock.ParentHash.String())
|
| 141 |
+
}
|
| 142 |
+
log.Errorf(msg)
|
| 143 |
+
return common.NewReorgError(stateBlock.BlockNumber, fmt.Errorf(msg))
|
| 144 |
+
}
|
| 145 |
+
return nil
|
| 146 |
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package l1_check_block_test
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"context"
|
| 5 |
+
"fmt"
|
| 6 |
+
"math/big"
|
| 7 |
+
"testing"
|
| 8 |
+
|
| 9 |
+
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 10 |
+
commonsync "github.com/0xPolygonHermez/zkevm-node/synchronizer/common"
|
| 11 |
+
"github.com/0xPolygonHermez/zkevm-node/synchronizer/l1_check_block"
|
| 12 |
+
mock_l1_check_block "github.com/0xPolygonHermez/zkevm-node/synchronizer/l1_check_block/mocks"
|
| 13 |
+
"github.com/ethereum/go-ethereum/common"
|
| 14 |
+
"github.com/ethereum/go-ethereum/core/types"
|
| 15 |
+
"github.com/stretchr/testify/mock"
|
| 16 |
+
"github.com/stretchr/testify/require"
|
| 17 |
+
)
|
| 18 |
+
|
| 19 |
+
type testData struct {
|
| 20 |
+
mockL1Client *mock_l1_check_block.L1Requester
|
| 21 |
+
mockState *mock_l1_check_block.StateInterfacer
|
| 22 |
+
mockBlockNumberFetch *mock_l1_check_block.SafeL1BlockNumberFetcher
|
| 23 |
+
sut *l1_check_block.CheckL1BlockHash
|
| 24 |
+
ctx context.Context
|
| 25 |
+
stateBlock *state.Block
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
func newTestData(t *testing.T) *testData {
|
| 29 |
+
mockL1Client := mock_l1_check_block.NewL1Requester(t)
|
| 30 |
+
mockState := mock_l1_check_block.NewStateInterfacer(t)
|
| 31 |
+
mockBlockNumberFetch := mock_l1_check_block.NewSafeL1BlockNumberFetcher(t)
|
| 32 |
+
mockBlockNumberFetch.EXPECT().Description().Return("mock").Maybe()
|
| 33 |
+
sut := l1_check_block.NewCheckL1BlockHash(mockL1Client, mockState, mockBlockNumberFetch)
|
| 34 |
+
require.NotNil(t, sut)
|
| 35 |
+
ctx := context.Background()
|
| 36 |
+
return &testData{
|
| 37 |
+
mockL1Client: mockL1Client,
|
| 38 |
+
mockState: mockState,
|
| 39 |
+
mockBlockNumberFetch: mockBlockNumberFetch,
|
| 40 |
+
sut: sut,
|
| 41 |
+
ctx: ctx,
|
| 42 |
+
stateBlock: &state.Block{
|
| 43 |
+
BlockNumber: 1234,
|
| 44 |
+
BlockHash: common.HexToHash("0xb07e1289b32edefd8f3c702d016fb73c81d5950b2ebc790ad9d2cb8219066b4c"),
|
| 45 |
+
},
|
| 46 |
+
}
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
func TestCheckL1BlockHashNoBlocksOnDB(t *testing.T) {
|
| 50 |
+
data := newTestData(t)
|
| 51 |
+
data.mockState.EXPECT().GetFirstUncheckedBlock(data.ctx, uint64(0), nil).Return(nil, state.ErrNotFound)
|
| 52 |
+
res := data.sut.Step(data.ctx)
|
| 53 |
+
require.NoError(t, res)
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
func TestCheckL1BlockHashErrorGettingFirstUncheckedBlockFromDB(t *testing.T) {
|
| 57 |
+
data := newTestData(t)
|
| 58 |
+
data.mockState.EXPECT().GetFirstUncheckedBlock(data.ctx, uint64(0), nil).Return(nil, fmt.Errorf("error"))
|
| 59 |
+
res := data.sut.Step(data.ctx)
|
| 60 |
+
require.Error(t, res)
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
func TestCheckL1BlockHashErrorGettingGetSafeBlockNumber(t *testing.T) {
|
| 64 |
+
data := newTestData(t)
|
| 65 |
+
|
| 66 |
+
data.mockState.EXPECT().GetFirstUncheckedBlock(data.ctx, uint64(0), nil).Return(data.stateBlock, nil)
|
| 67 |
+
data.mockBlockNumberFetch.EXPECT().GetSafeBlockNumber(data.ctx, data.mockL1Client).Return(uint64(0), fmt.Errorf("error"))
|
| 68 |
+
res := data.sut.Step(data.ctx)
|
| 69 |
+
require.Error(t, res)
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
// The first block to check is below the safe point, nothing to do
|
| 73 |
+
func TestCheckL1BlockHashSafePointIsInFuture(t *testing.T) {
|
| 74 |
+
data := newTestData(t)
|
| 75 |
+
|
| 76 |
+
data.mockState.EXPECT().GetFirstUncheckedBlock(data.ctx, uint64(0), nil).Return(data.stateBlock, nil)
|
| 77 |
+
data.mockBlockNumberFetch.EXPECT().GetSafeBlockNumber(data.ctx, data.mockL1Client).Return(data.stateBlock.BlockNumber-1, nil)
|
| 78 |
+
|
| 79 |
+
res := data.sut.Step(data.ctx)
|
| 80 |
+
require.NoError(t, res)
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
func TestCheckL1BlockHashL1ClientReturnsANil(t *testing.T) {
|
| 84 |
+
data := newTestData(t)
|
| 85 |
+
|
| 86 |
+
data.mockState.EXPECT().GetFirstUncheckedBlock(data.ctx, uint64(0), nil).Return(data.stateBlock, nil)
|
| 87 |
+
data.mockBlockNumberFetch.EXPECT().GetSafeBlockNumber(data.ctx, data.mockL1Client).Return(data.stateBlock.BlockNumber+10, nil)
|
| 88 |
+
data.mockL1Client.EXPECT().HeaderByNumber(data.ctx, big.NewInt(int64(data.stateBlock.BlockNumber))).Return(nil, nil)
|
| 89 |
+
res := data.sut.Step(data.ctx)
|
| 90 |
+
require.Error(t, res)
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
// Check a block that is OK
|
| 94 |
+
func TestCheckL1BlockHashMatchHashUpdateCheckMarkOnDB(t *testing.T) {
|
| 95 |
+
data := newTestData(t)
|
| 96 |
+
|
| 97 |
+
data.mockState.EXPECT().GetFirstUncheckedBlock(data.ctx, uint64(0), nil).Return(data.stateBlock, nil)
|
| 98 |
+
data.mockBlockNumberFetch.EXPECT().Description().Return("mock")
|
| 99 |
+
data.mockBlockNumberFetch.EXPECT().GetSafeBlockNumber(data.ctx, data.mockL1Client).Return(data.stateBlock.BlockNumber, nil)
|
| 100 |
+
l1Block := &types.Header{
|
| 101 |
+
Number: big.NewInt(100),
|
| 102 |
+
}
|
| 103 |
+
data.mockL1Client.EXPECT().HeaderByNumber(data.ctx, big.NewInt(int64(data.stateBlock.BlockNumber))).Return(l1Block, nil)
|
| 104 |
+
data.mockState.EXPECT().UpdateCheckedBlockByNumber(data.ctx, data.stateBlock.BlockNumber, true, nil).Return(nil)
|
| 105 |
+
data.mockState.EXPECT().GetFirstUncheckedBlock(data.ctx, mock.Anything, nil).Return(nil, state.ErrNotFound)
|
| 106 |
+
|
| 107 |
+
res := data.sut.Step(data.ctx)
|
| 108 |
+
require.NoError(t, res)
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
// The first block to check is equal to the safe point, must be processed
|
| 112 |
+
func TestCheckL1BlockHashMismatch(t *testing.T) {
|
| 113 |
+
data := newTestData(t)
|
| 114 |
+
|
| 115 |
+
data.mockState.EXPECT().GetFirstUncheckedBlock(data.ctx, uint64(0), nil).Return(data.stateBlock, nil)
|
| 116 |
+
data.stateBlock.BlockHash = common.HexToHash("0x1234") // Wrong hash to trigger a mismatch
|
| 117 |
+
data.mockBlockNumberFetch.EXPECT().GetSafeBlockNumber(data.ctx, data.mockL1Client).Return(data.stateBlock.BlockNumber, nil)
|
| 118 |
+
l1Block := &types.Header{
|
| 119 |
+
Number: big.NewInt(100),
|
| 120 |
+
}
|
| 121 |
+
data.mockL1Client.EXPECT().HeaderByNumber(data.ctx, big.NewInt(int64(data.stateBlock.BlockNumber))).Return(l1Block, nil)
|
| 122 |
+
|
| 123 |
+
res := data.sut.Step(data.ctx)
|
| 124 |
+
require.Error(t, res)
|
| 125 |
+
resErr, ok := res.(*commonsync.ReorgError)
|
| 126 |
+
require.True(t, ok)
|
| 127 |
+
require.Equal(t, data.stateBlock.BlockNumber, resErr.BlockNumber)
|
| 128 |
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package l1_check_block
|
| 2 |
+
|
| 3 |
+
const (
|
| 4 |
+
logPrefix = "checkL1block:"
|
| 5 |
+
)
|
|
@@ -0,0 +1,205 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package l1_check_block
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"context"
|
| 5 |
+
"time"
|
| 6 |
+
|
| 7 |
+
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 8 |
+
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 9 |
+
"github.com/0xPolygonHermez/zkevm-node/synchronizer/common/syncinterfaces"
|
| 10 |
+
"github.com/jackc/pgx/v4"
|
| 11 |
+
)
|
| 12 |
+
|
| 13 |
+
// StateForL1BlockCheckerIntegration is an interface for the state
|
| 14 |
+
type StateForL1BlockCheckerIntegration interface {
|
| 15 |
+
GetPreviousBlockToBlockNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (*state.Block, error)
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
// L1BlockCheckerIntegration is a struct that integrates the L1BlockChecker with the synchronizer
|
| 19 |
+
type L1BlockCheckerIntegration struct {
|
| 20 |
+
forceCheckOnStart bool
|
| 21 |
+
checker syncinterfaces.AsyncL1BlockChecker
|
| 22 |
+
preChecker syncinterfaces.AsyncL1BlockChecker
|
| 23 |
+
state StateForL1BlockCheckerIntegration
|
| 24 |
+
sync SyncCheckReorger
|
| 25 |
+
timeBetweenRetries time.Duration
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
// SyncCheckReorger is an interface that defines the methods required from Synchronizer object
|
| 29 |
+
type SyncCheckReorger interface {
|
| 30 |
+
ExecuteReorgFromMismatchBlock(blockNumber uint64, reason string) error
|
| 31 |
+
OnDetectedMismatchL1BlockReorg()
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
// NewL1BlockCheckerIntegration creates a new L1BlockCheckerIntegration
|
| 35 |
+
func NewL1BlockCheckerIntegration(checker syncinterfaces.AsyncL1BlockChecker, preChecker syncinterfaces.AsyncL1BlockChecker, state StateForL1BlockCheckerIntegration, sync SyncCheckReorger, forceCheckOnStart bool, timeBetweenRetries time.Duration) *L1BlockCheckerIntegration {
|
| 36 |
+
return &L1BlockCheckerIntegration{
|
| 37 |
+
forceCheckOnStart: forceCheckOnStart,
|
| 38 |
+
checker: checker,
|
| 39 |
+
preChecker: preChecker,
|
| 40 |
+
state: state,
|
| 41 |
+
sync: sync,
|
| 42 |
+
timeBetweenRetries: timeBetweenRetries,
|
| 43 |
+
}
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
// OnStart is a method that is called before starting the synchronizer
|
| 47 |
+
func (v *L1BlockCheckerIntegration) OnStart(ctx context.Context) error {
|
| 48 |
+
if v.forceCheckOnStart {
|
| 49 |
+
log.Infof("%s Forcing L1BlockChecker check before start", logPrefix)
|
| 50 |
+
result := v.runCheckerSync(ctx, v.checker)
|
| 51 |
+
if result.ReorgDetected {
|
| 52 |
+
v.executeResult(ctx, result)
|
| 53 |
+
} else {
|
| 54 |
+
log.Infof("%s Forcing L1BlockChecker check:OK ", logPrefix)
|
| 55 |
+
if v.preChecker != nil {
|
| 56 |
+
log.Infof("%s Forcing L1BlockChecker preCheck before start", logPrefix)
|
| 57 |
+
result = v.runCheckerSync(ctx, v.preChecker)
|
| 58 |
+
if result.ReorgDetected {
|
| 59 |
+
v.executeResult(ctx, result)
|
| 60 |
+
} else {
|
| 61 |
+
log.Infof("%s Forcing L1BlockChecker preCheck:OK", logPrefix)
|
| 62 |
+
}
|
| 63 |
+
}
|
| 64 |
+
}
|
| 65 |
+
}
|
| 66 |
+
v.launch(ctx)
|
| 67 |
+
return nil
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
func (v *L1BlockCheckerIntegration) runCheckerSync(ctx context.Context, checker syncinterfaces.AsyncL1BlockChecker) syncinterfaces.IterationResult {
|
| 71 |
+
for {
|
| 72 |
+
result := checker.RunSynchronous(ctx)
|
| 73 |
+
if result.Err == nil {
|
| 74 |
+
return result
|
| 75 |
+
} else {
|
| 76 |
+
time.Sleep(v.timeBetweenRetries)
|
| 77 |
+
}
|
| 78 |
+
}
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
// OnStartL1Sync is a method that is called before starting the L1 sync
|
| 82 |
+
func (v *L1BlockCheckerIntegration) OnStartL1Sync(ctx context.Context) bool {
|
| 83 |
+
return v.checkBackgroundResult(ctx, "before start L1 sync")
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
// OnStartL2Sync is a method that is called before starting the L2 sync
|
| 87 |
+
func (v *L1BlockCheckerIntegration) OnStartL2Sync(ctx context.Context) bool {
|
| 88 |
+
return v.checkBackgroundResult(ctx, "before start 2 sync")
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
// OnResetState is a method that is called after a resetState
|
| 92 |
+
func (v *L1BlockCheckerIntegration) OnResetState(ctx context.Context) {
|
| 93 |
+
log.Infof("%s L1BlockChecker: after a resetState relaunch background process", logPrefix)
|
| 94 |
+
v.launch(ctx)
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
// CheckReorgWrapper is a wrapper over reorg function of synchronizer.
|
| 98 |
+
// it checks the result of the function and the result of background process and decides which return
|
| 99 |
+
func (v *L1BlockCheckerIntegration) CheckReorgWrapper(ctx context.Context, reorgFirstBlockOk *state.Block, errReportedByReorgFunc error) (*state.Block, error) {
|
| 100 |
+
resultBackground := v.getMergedResults()
|
| 101 |
+
if resultBackground != nil && resultBackground.ReorgDetected {
|
| 102 |
+
// Background process detected a reorg, decide which return
|
| 103 |
+
firstOkBlockBackgroundCheck, err := v.state.GetPreviousBlockToBlockNumber(ctx, resultBackground.BlockNumber, nil)
|
| 104 |
+
if err != nil {
|
| 105 |
+
log.Warnf("%s Error getting previous block to block number where a reorg have been detected %d: %s. So we reorgFunc values", logPrefix, resultBackground.BlockNumber, err)
|
| 106 |
+
return reorgFirstBlockOk, errReportedByReorgFunc
|
| 107 |
+
}
|
| 108 |
+
if reorgFirstBlockOk == nil || errReportedByReorgFunc != nil {
|
| 109 |
+
log.Infof("%s Background checker detects bad block at block %d (first block ok %d) and regular reorg function no. Returning it", logPrefix,
|
| 110 |
+
resultBackground.BlockNumber, firstOkBlockBackgroundCheck.BlockNumber)
|
| 111 |
+
return firstOkBlockBackgroundCheck, nil
|
| 112 |
+
}
|
| 113 |
+
if firstOkBlockBackgroundCheck.BlockNumber < reorgFirstBlockOk.BlockNumber {
|
| 114 |
+
// Background process detected a reorg at oldest block
|
| 115 |
+
log.Warnf("%s Background checker detects bad block at block %d (first block ok %d) and regular reorg function first block ok: %d. Returning from %d",
|
| 116 |
+
logPrefix, resultBackground.BlockNumber, firstOkBlockBackgroundCheck.BlockNumber, reorgFirstBlockOk.BlockNumber, firstOkBlockBackgroundCheck.BlockNumber)
|
| 117 |
+
return firstOkBlockBackgroundCheck, nil
|
| 118 |
+
} else {
|
| 119 |
+
// Regular reorg function detected a reorg at oldest block
|
| 120 |
+
log.Warnf("%s Background checker detects bad block at block %d (first block ok %d) and regular reorg function first block ok: %d. Executing from %d",
|
| 121 |
+
logPrefix, resultBackground.BlockNumber, firstOkBlockBackgroundCheck.BlockNumber, reorgFirstBlockOk.BlockNumber, reorgFirstBlockOk.BlockNumber)
|
| 122 |
+
return reorgFirstBlockOk, errReportedByReorgFunc
|
| 123 |
+
}
|
| 124 |
+
}
|
| 125 |
+
if resultBackground != nil && !resultBackground.ReorgDetected {
|
| 126 |
+
// Relaunch checker, if there is a reorg, It is going to be relaunched after (OnResetState)
|
| 127 |
+
v.launch(ctx)
|
| 128 |
+
}
|
| 129 |
+
// Background process doesnt have anything to we return the regular reorg function result
|
| 130 |
+
return reorgFirstBlockOk, errReportedByReorgFunc
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
func (v *L1BlockCheckerIntegration) checkBackgroundResult(ctx context.Context, positionMessage string) bool {
|
| 134 |
+
log.Debugf("%s Checking L1BlockChecker %s", logPrefix, positionMessage)
|
| 135 |
+
result := v.getMergedResults()
|
| 136 |
+
if result != nil {
|
| 137 |
+
if result.ReorgDetected {
|
| 138 |
+
log.Warnf("%s Checking L1BlockChecker %s: reorg detected %s", logPrefix, positionMessage, result.String())
|
| 139 |
+
v.executeResult(ctx, *result)
|
| 140 |
+
}
|
| 141 |
+
v.launch(ctx)
|
| 142 |
+
return result.ReorgDetected
|
| 143 |
+
}
|
| 144 |
+
return false
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
func (v *L1BlockCheckerIntegration) getMergedResults() *syncinterfaces.IterationResult {
|
| 148 |
+
result := v.checker.GetResult()
|
| 149 |
+
var preResult *syncinterfaces.IterationResult
|
| 150 |
+
preResult = nil
|
| 151 |
+
if v.preChecker != nil {
|
| 152 |
+
preResult = v.preChecker.GetResult()
|
| 153 |
+
}
|
| 154 |
+
if preResult == nil {
|
| 155 |
+
return result
|
| 156 |
+
}
|
| 157 |
+
if result == nil {
|
| 158 |
+
return preResult
|
| 159 |
+
}
|
| 160 |
+
// result and preResult have values
|
| 161 |
+
if result.ReorgDetected && preResult.ReorgDetected {
|
| 162 |
+
// That is the common case, checker must detect oldest blocks than preChecker
|
| 163 |
+
if result.BlockNumber < preResult.BlockNumber {
|
| 164 |
+
return result
|
| 165 |
+
}
|
| 166 |
+
return preResult
|
| 167 |
+
}
|
| 168 |
+
if preResult.ReorgDetected {
|
| 169 |
+
return preResult
|
| 170 |
+
}
|
| 171 |
+
return result
|
| 172 |
+
}
|
| 173 |
+
|
| 174 |
+
func (v *L1BlockCheckerIntegration) onFinishChecker() {
|
| 175 |
+
log.Infof("%s L1BlockChecker: finished background process, calling to synchronizer", logPrefix)
|
| 176 |
+
// Stop both processes
|
| 177 |
+
v.checker.Stop()
|
| 178 |
+
if v.preChecker != nil {
|
| 179 |
+
v.preChecker.Stop()
|
| 180 |
+
}
|
| 181 |
+
v.sync.OnDetectedMismatchL1BlockReorg()
|
| 182 |
+
}
|
| 183 |
+
|
| 184 |
+
func (v *L1BlockCheckerIntegration) launch(ctx context.Context) {
|
| 185 |
+
log.Infof("%s L1BlockChecker: starting background process...", logPrefix)
|
| 186 |
+
v.checker.Run(ctx, v.onFinishChecker)
|
| 187 |
+
if v.preChecker != nil {
|
| 188 |
+
log.Infof("%s L1BlockChecker: starting background precheck process...", logPrefix)
|
| 189 |
+
v.preChecker.Run(ctx, v.onFinishChecker)
|
| 190 |
+
}
|
| 191 |
+
}
|
| 192 |
+
|
| 193 |
+
func (v *L1BlockCheckerIntegration) executeResult(ctx context.Context, result syncinterfaces.IterationResult) bool {
|
| 194 |
+
if result.ReorgDetected {
|
| 195 |
+
for {
|
| 196 |
+
err := v.sync.ExecuteReorgFromMismatchBlock(result.BlockNumber, result.ReorgMessage)
|
| 197 |
+
if err == nil {
|
| 198 |
+
return true
|
| 199 |
+
}
|
| 200 |
+
log.Errorf("%s Error executing reorg: %s", logPrefix, err)
|
| 201 |
+
time.Sleep(v.timeBetweenRetries)
|
| 202 |
+
}
|
| 203 |
+
}
|
| 204 |
+
return false
|
| 205 |
+
}
|
|
@@ -0,0 +1,298 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package l1_check_block_test
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"context"
|
| 5 |
+
"fmt"
|
| 6 |
+
"testing"
|
| 7 |
+
"time"
|
| 8 |
+
|
| 9 |
+
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 10 |
+
"github.com/0xPolygonHermez/zkevm-node/synchronizer/common/syncinterfaces"
|
| 11 |
+
mock_syncinterfaces "github.com/0xPolygonHermez/zkevm-node/synchronizer/common/syncinterfaces/mocks"
|
| 12 |
+
"github.com/0xPolygonHermez/zkevm-node/synchronizer/l1_check_block"
|
| 13 |
+
mock_l1_check_block "github.com/0xPolygonHermez/zkevm-node/synchronizer/l1_check_block/mocks"
|
| 14 |
+
"github.com/stretchr/testify/mock"
|
| 15 |
+
"github.com/stretchr/testify/require"
|
| 16 |
+
)
|
| 17 |
+
|
| 18 |
+
var (
|
| 19 |
+
genericErrorToTest = fmt.Errorf("error")
|
| 20 |
+
)
|
| 21 |
+
|
| 22 |
+
type testDataIntegration struct {
|
| 23 |
+
mockChecker *mock_syncinterfaces.AsyncL1BlockChecker
|
| 24 |
+
mockPreChecker *mock_syncinterfaces.AsyncL1BlockChecker
|
| 25 |
+
mockState *mock_l1_check_block.StateForL1BlockCheckerIntegration
|
| 26 |
+
mockSync *mock_l1_check_block.SyncCheckReorger
|
| 27 |
+
sut *l1_check_block.L1BlockCheckerIntegration
|
| 28 |
+
ctx context.Context
|
| 29 |
+
resultOk syncinterfaces.IterationResult
|
| 30 |
+
resultError syncinterfaces.IterationResult
|
| 31 |
+
resultReorg syncinterfaces.IterationResult
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
func newDataIntegration(t *testing.T, forceCheckOnStart bool) *testDataIntegration {
|
| 35 |
+
return newDataIntegrationOnlyMainChecker(t, forceCheckOnStart)
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
func newDataIntegrationWithPreChecker(t *testing.T, forceCheckOnStart bool) *testDataIntegration {
|
| 39 |
+
res := newDataIntegrationOnlyMainChecker(t, forceCheckOnStart)
|
| 40 |
+
res.mockPreChecker = mock_syncinterfaces.NewAsyncL1BlockChecker(t)
|
| 41 |
+
res.sut = l1_check_block.NewL1BlockCheckerIntegration(res.mockChecker, res.mockPreChecker, res.mockState, res.mockSync, forceCheckOnStart, time.Millisecond)
|
| 42 |
+
return res
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
func newDataIntegrationOnlyMainChecker(t *testing.T, forceCheckOnStart bool) *testDataIntegration {
|
| 46 |
+
mockChecker := mock_syncinterfaces.NewAsyncL1BlockChecker(t)
|
| 47 |
+
mockSync := mock_l1_check_block.NewSyncCheckReorger(t)
|
| 48 |
+
mockState := mock_l1_check_block.NewStateForL1BlockCheckerIntegration(t)
|
| 49 |
+
sut := l1_check_block.NewL1BlockCheckerIntegration(mockChecker, nil, mockState, mockSync, forceCheckOnStart, time.Millisecond)
|
| 50 |
+
return &testDataIntegration{
|
| 51 |
+
mockChecker: mockChecker,
|
| 52 |
+
mockPreChecker: nil,
|
| 53 |
+
mockSync: mockSync,
|
| 54 |
+
mockState: mockState,
|
| 55 |
+
sut: sut,
|
| 56 |
+
ctx: context.Background(),
|
| 57 |
+
resultReorg: syncinterfaces.IterationResult{
|
| 58 |
+
ReorgDetected: true,
|
| 59 |
+
BlockNumber: 1234,
|
| 60 |
+
},
|
| 61 |
+
resultOk: syncinterfaces.IterationResult{
|
| 62 |
+
ReorgDetected: false,
|
| 63 |
+
},
|
| 64 |
+
resultError: syncinterfaces.IterationResult{
|
| 65 |
+
Err: genericErrorToTest,
|
| 66 |
+
ReorgDetected: false,
|
| 67 |
+
},
|
| 68 |
+
}
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
func TestIntegrationIfNoForceCheckOnlyLaunchBackgroudChecker(t *testing.T) {
|
| 72 |
+
data := newDataIntegration(t, false)
|
| 73 |
+
data.mockChecker.EXPECT().Run(data.ctx, mock.Anything).Return()
|
| 74 |
+
err := data.sut.OnStart(data.ctx)
|
| 75 |
+
require.NoError(t, err)
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
func TestIntegrationIfForceCheckRunsSynchronousOneTimeAndAfterLaunchBackgroudChecker(t *testing.T) {
|
| 79 |
+
data := newDataIntegration(t, true)
|
| 80 |
+
data.mockChecker.EXPECT().RunSynchronous(data.ctx).Return(data.resultOk)
|
| 81 |
+
data.mockChecker.EXPECT().Run(data.ctx, mock.Anything).Return()
|
| 82 |
+
err := data.sut.OnStart(data.ctx)
|
| 83 |
+
require.NoError(t, err)
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
func TestIntegrationIfSyncCheckReturnsReorgExecuteIt(t *testing.T) {
|
| 87 |
+
data := newDataIntegration(t, true)
|
| 88 |
+
data.mockChecker.EXPECT().RunSynchronous(data.ctx).Return(data.resultReorg)
|
| 89 |
+
data.mockSync.EXPECT().ExecuteReorgFromMismatchBlock(uint64(1234), "").Return(nil)
|
| 90 |
+
data.mockChecker.EXPECT().Run(data.ctx, mock.Anything).Return()
|
| 91 |
+
err := data.sut.OnStart(data.ctx)
|
| 92 |
+
require.NoError(t, err)
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
func TestIntegrationIfSyncCheckReturnErrorRetry(t *testing.T) {
|
| 96 |
+
data := newDataIntegration(t, true)
|
| 97 |
+
data.mockChecker.EXPECT().RunSynchronous(data.ctx).Return(data.resultError).Once()
|
| 98 |
+
data.mockChecker.EXPECT().RunSynchronous(data.ctx).Return(data.resultOk).Once()
|
| 99 |
+
data.mockChecker.EXPECT().Run(data.ctx, mock.Anything).Return()
|
| 100 |
+
err := data.sut.OnStart(data.ctx)
|
| 101 |
+
require.NoError(t, err)
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
func TestIntegrationIfSyncCheckReturnsReorgExecuteItAndFailsRetry(t *testing.T) {
|
| 105 |
+
data := newDataIntegration(t, true)
|
| 106 |
+
data.mockChecker.EXPECT().RunSynchronous(data.ctx).Return(data.resultReorg)
|
| 107 |
+
data.mockSync.EXPECT().ExecuteReorgFromMismatchBlock(uint64(1234), mock.Anything).Return(genericErrorToTest).Once()
|
| 108 |
+
data.mockSync.EXPECT().ExecuteReorgFromMismatchBlock(uint64(1234), mock.Anything).Return(nil).Once()
|
| 109 |
+
data.mockChecker.EXPECT().Run(data.ctx, mock.Anything).Return()
|
| 110 |
+
err := data.sut.OnStart(data.ctx)
|
| 111 |
+
require.NoError(t, err)
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
// OnStart if check and preCheck execute both, and launch both in background
|
| 115 |
+
func TestIntegrationCheckAndPreCheckOnStartForceCheck(t *testing.T) {
|
| 116 |
+
data := newDataIntegrationWithPreChecker(t, true)
|
| 117 |
+
data.mockChecker.EXPECT().RunSynchronous(data.ctx).Return(data.resultOk)
|
| 118 |
+
data.mockPreChecker.EXPECT().RunSynchronous(data.ctx).Return(data.resultOk)
|
| 119 |
+
data.mockChecker.EXPECT().Run(data.ctx, mock.Anything).Return()
|
| 120 |
+
data.mockPreChecker.EXPECT().Run(data.ctx, mock.Anything).Return()
|
| 121 |
+
err := data.sut.OnStart(data.ctx)
|
| 122 |
+
require.NoError(t, err)
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
// OnStart if mainChecker returns reorg doesnt need to run preCheck
|
| 126 |
+
func TestIntegrationCheckAndPreCheckOnStartMainCheckerReturnReorg(t *testing.T) {
|
| 127 |
+
data := newDataIntegrationWithPreChecker(t, true)
|
| 128 |
+
data.mockChecker.EXPECT().RunSynchronous(data.ctx).Return(data.resultReorg)
|
| 129 |
+
data.mockSync.EXPECT().ExecuteReorgFromMismatchBlock(uint64(1234), mock.Anything).Return(nil).Once()
|
| 130 |
+
data.mockChecker.EXPECT().Run(data.ctx, mock.Anything).Return()
|
| 131 |
+
data.mockPreChecker.EXPECT().Run(data.ctx, mock.Anything).Return()
|
| 132 |
+
err := data.sut.OnStart(data.ctx)
|
| 133 |
+
require.NoError(t, err)
|
| 134 |
+
}
|
| 135 |
+
|
| 136 |
+
// If mainCheck is OK, but preCheck returns reorg, it should execute reorg
|
| 137 |
+
func TestIntegrationCheckAndPreCheckOnStartPreCheckerReturnReorg(t *testing.T) {
|
| 138 |
+
data := newDataIntegrationWithPreChecker(t, true)
|
| 139 |
+
data.mockChecker.EXPECT().RunSynchronous(data.ctx).Return(data.resultOk)
|
| 140 |
+
data.mockPreChecker.EXPECT().RunSynchronous(data.ctx).Return(data.resultReorg)
|
| 141 |
+
data.mockSync.EXPECT().ExecuteReorgFromMismatchBlock(uint64(1234), mock.Anything).Return(nil).Once()
|
| 142 |
+
data.mockChecker.EXPECT().Run(data.ctx, mock.Anything).Return()
|
| 143 |
+
data.mockPreChecker.EXPECT().Run(data.ctx, mock.Anything).Return()
|
| 144 |
+
err := data.sut.OnStart(data.ctx)
|
| 145 |
+
require.NoError(t, err)
|
| 146 |
+
}
|
| 147 |
+
|
| 148 |
+
// The process is running on background, no results yet
|
| 149 |
+
func TestIntegrationCheckAndPreCheckOnOnCheckReorgRunningOnBackground(t *testing.T) {
|
| 150 |
+
data := newDataIntegrationWithPreChecker(t, true)
|
| 151 |
+
data.mockChecker.EXPECT().GetResult().Return(nil)
|
| 152 |
+
data.mockPreChecker.EXPECT().GetResult().Return(nil)
|
| 153 |
+
block, err := data.sut.CheckReorgWrapper(data.ctx, nil, nil)
|
| 154 |
+
require.Nil(t, block)
|
| 155 |
+
require.NoError(t, err)
|
| 156 |
+
}
|
| 157 |
+
|
| 158 |
+
func TestIntegrationCheckAndPreCheckOnOnCheckReorgOneProcessHaveResultOK(t *testing.T) {
|
| 159 |
+
data := newDataIntegrationWithPreChecker(t, true)
|
| 160 |
+
data.mockChecker.EXPECT().GetResult().Return(&data.resultOk)
|
| 161 |
+
data.mockPreChecker.EXPECT().GetResult().Return(nil)
|
| 162 |
+
// One have been stopped, so must relaunch both
|
| 163 |
+
data.mockChecker.EXPECT().Run(data.ctx, mock.Anything).Return()
|
| 164 |
+
data.mockPreChecker.EXPECT().Run(data.ctx, mock.Anything).Return()
|
| 165 |
+
block, err := data.sut.CheckReorgWrapper(data.ctx, nil, nil)
|
| 166 |
+
require.Nil(t, block)
|
| 167 |
+
require.NoError(t, err)
|
| 168 |
+
}
|
| 169 |
+
|
| 170 |
+
func TestIntegrationCheckAndPreCheckOnOnCheckReorgMainCheckerReorg(t *testing.T) {
|
| 171 |
+
data := newDataIntegrationWithPreChecker(t, true)
|
| 172 |
+
data.mockChecker.EXPECT().GetResult().Return(&data.resultReorg)
|
| 173 |
+
data.mockPreChecker.EXPECT().GetResult().Return(nil)
|
| 174 |
+
data.mockState.EXPECT().GetPreviousBlockToBlockNumber(data.ctx, uint64(1234), nil).Return(&state.Block{
|
| 175 |
+
BlockNumber: data.resultReorg.BlockNumber - 1,
|
| 176 |
+
}, nil)
|
| 177 |
+
// One have been stopped,but is going to be launched OnResetState call after the reset
|
| 178 |
+
block, err := data.sut.CheckReorgWrapper(data.ctx, nil, nil)
|
| 179 |
+
require.NotNil(t, block)
|
| 180 |
+
require.Equal(t, data.resultReorg.BlockNumber-1, block.BlockNumber)
|
| 181 |
+
require.NoError(t, err)
|
| 182 |
+
}
|
| 183 |
+
|
| 184 |
+
func TestIntegrationCheckAndPreCheckOnOnCheckReorgPreCheckerReorg(t *testing.T) {
|
| 185 |
+
data := newDataIntegrationWithPreChecker(t, true)
|
| 186 |
+
data.mockChecker.EXPECT().GetResult().Return(nil)
|
| 187 |
+
data.mockPreChecker.EXPECT().GetResult().Return(&data.resultReorg)
|
| 188 |
+
data.mockState.EXPECT().GetPreviousBlockToBlockNumber(data.ctx, uint64(1234), nil).Return(&state.Block{
|
| 189 |
+
BlockNumber: data.resultReorg.BlockNumber - 1,
|
| 190 |
+
}, nil)
|
| 191 |
+
// One have been stopped,but is going to be launched OnResetState call after the reset
|
| 192 |
+
|
| 193 |
+
block, err := data.sut.CheckReorgWrapper(data.ctx, nil, nil)
|
| 194 |
+
require.NotNil(t, block)
|
| 195 |
+
require.Equal(t, data.resultReorg.BlockNumber-1, block.BlockNumber)
|
| 196 |
+
require.NoError(t, err)
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
func TestIntegrationCheckAndPreCheckOnOnCheckReorgBothReorgWinOldest1(t *testing.T) {
|
| 200 |
+
data := newDataIntegrationWithPreChecker(t, true)
|
| 201 |
+
reorgMain := data.resultReorg
|
| 202 |
+
reorgMain.BlockNumber = 1235
|
| 203 |
+
data.mockChecker.EXPECT().GetResult().Return(&reorgMain)
|
| 204 |
+
reorgPre := data.resultReorg
|
| 205 |
+
reorgPre.BlockNumber = 1236
|
| 206 |
+
data.mockPreChecker.EXPECT().GetResult().Return(&reorgPre)
|
| 207 |
+
data.mockState.EXPECT().GetPreviousBlockToBlockNumber(data.ctx, uint64(1235), nil).Return(&state.Block{
|
| 208 |
+
BlockNumber: 1234,
|
| 209 |
+
}, nil)
|
| 210 |
+
|
| 211 |
+
// Both have been stopped,but is going to be launched OnResetState call after the reset
|
| 212 |
+
|
| 213 |
+
block, err := data.sut.CheckReorgWrapper(data.ctx, nil, nil)
|
| 214 |
+
require.NotNil(t, block)
|
| 215 |
+
require.Equal(t, uint64(1234), block.BlockNumber)
|
| 216 |
+
require.NoError(t, err)
|
| 217 |
+
}
|
| 218 |
+
|
| 219 |
+
func TestIntegrationCheckAndPreCheckOnOnCheckReorgBothReorgWinOldest2(t *testing.T) {
|
| 220 |
+
data := newDataIntegrationWithPreChecker(t, true)
|
| 221 |
+
reorgMain := data.resultReorg
|
| 222 |
+
reorgMain.BlockNumber = 1236
|
| 223 |
+
data.mockChecker.EXPECT().GetResult().Return(&reorgMain)
|
| 224 |
+
reorgPre := data.resultReorg
|
| 225 |
+
reorgPre.BlockNumber = 1235
|
| 226 |
+
data.mockPreChecker.EXPECT().GetResult().Return(&reorgPre)
|
| 227 |
+
data.mockState.EXPECT().GetPreviousBlockToBlockNumber(data.ctx, uint64(1235), nil).Return(&state.Block{
|
| 228 |
+
BlockNumber: 1234,
|
| 229 |
+
}, nil)
|
| 230 |
+
// Both have been stopped,but is going to be launched OnResetState call after the reset
|
| 231 |
+
|
| 232 |
+
block, err := data.sut.CheckReorgWrapper(data.ctx, nil, nil)
|
| 233 |
+
require.NotNil(t, block)
|
| 234 |
+
require.Equal(t, uint64(1234), block.BlockNumber)
|
| 235 |
+
require.NoError(t, err)
|
| 236 |
+
}
|
| 237 |
+
|
| 238 |
+
func TestIntegrationCheckReorgWrapperBypassReorgFuncIfNoBackgroundData(t *testing.T) {
|
| 239 |
+
data := newDataIntegrationWithPreChecker(t, true)
|
| 240 |
+
data.mockChecker.EXPECT().GetResult().Return(nil)
|
| 241 |
+
data.mockPreChecker.EXPECT().GetResult().Return(nil)
|
| 242 |
+
reorgFuncBlock := &state.Block{
|
| 243 |
+
BlockNumber: 1234,
|
| 244 |
+
}
|
| 245 |
+
reorgFuncErr := fmt.Errorf("error")
|
| 246 |
+
block, err := data.sut.CheckReorgWrapper(data.ctx, reorgFuncBlock, reorgFuncErr)
|
| 247 |
+
require.Equal(t, reorgFuncBlock, block)
|
| 248 |
+
require.Equal(t, reorgFuncErr, err)
|
| 249 |
+
}
|
| 250 |
+
|
| 251 |
+
func TestIntegrationCheckReorgWrapperChooseOldestReorgFunc(t *testing.T) {
|
| 252 |
+
data := newDataIntegrationWithPreChecker(t, true)
|
| 253 |
+
data.mockChecker.EXPECT().GetResult().Return(nil)
|
| 254 |
+
data.mockPreChecker.EXPECT().GetResult().Return(&data.resultReorg)
|
| 255 |
+
data.mockState.EXPECT().GetPreviousBlockToBlockNumber(data.ctx, uint64(1234), nil).Return(&state.Block{
|
| 256 |
+
BlockNumber: 1233,
|
| 257 |
+
}, nil)
|
| 258 |
+
|
| 259 |
+
reorgFuncBlock := &state.Block{
|
| 260 |
+
BlockNumber: 1230,
|
| 261 |
+
}
|
| 262 |
+
block, err := data.sut.CheckReorgWrapper(data.ctx, reorgFuncBlock, nil)
|
| 263 |
+
require.Equal(t, reorgFuncBlock, block)
|
| 264 |
+
require.NoError(t, err)
|
| 265 |
+
}
|
| 266 |
+
|
| 267 |
+
func TestIntegrationCheckReorgWrapperChooseOldestBackgroundCheck(t *testing.T) {
|
| 268 |
+
data := newDataIntegrationWithPreChecker(t, true)
|
| 269 |
+
data.mockChecker.EXPECT().GetResult().Return(nil)
|
| 270 |
+
data.mockPreChecker.EXPECT().GetResult().Return(&data.resultReorg)
|
| 271 |
+
data.mockState.EXPECT().GetPreviousBlockToBlockNumber(data.ctx, uint64(1234), nil).Return(&state.Block{
|
| 272 |
+
BlockNumber: 1233,
|
| 273 |
+
}, nil)
|
| 274 |
+
|
| 275 |
+
reorgFuncBlock := &state.Block{
|
| 276 |
+
BlockNumber: 1240,
|
| 277 |
+
}
|
| 278 |
+
block, err := data.sut.CheckReorgWrapper(data.ctx, reorgFuncBlock, nil)
|
| 279 |
+
require.Equal(t, uint64(1233), block.BlockNumber)
|
| 280 |
+
require.NoError(t, err)
|
| 281 |
+
}
|
| 282 |
+
|
| 283 |
+
func TestIntegrationCheckReorgWrapperIgnoreReorgFuncIfError(t *testing.T) {
|
| 284 |
+
data := newDataIntegrationWithPreChecker(t, true)
|
| 285 |
+
data.mockChecker.EXPECT().GetResult().Return(nil)
|
| 286 |
+
data.mockPreChecker.EXPECT().GetResult().Return(&data.resultReorg)
|
| 287 |
+
data.mockState.EXPECT().GetPreviousBlockToBlockNumber(data.ctx, uint64(1234), nil).Return(&state.Block{
|
| 288 |
+
BlockNumber: 1233,
|
| 289 |
+
}, nil)
|
| 290 |
+
|
| 291 |
+
reorgFuncBlock := &state.Block{
|
| 292 |
+
BlockNumber: 1230,
|
| 293 |
+
}
|
| 294 |
+
reorgFuncErr := fmt.Errorf("error")
|
| 295 |
+
block, err := data.sut.CheckReorgWrapper(data.ctx, reorgFuncBlock, reorgFuncErr)
|
| 296 |
+
require.Equal(t, uint64(1233), block.BlockNumber)
|
| 297 |
+
require.NoError(t, err)
|
| 298 |
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package l1_check_block
|
| 2 |
+
|
| 3 |
+
// This make a pre-check of blocks but don't mark them as checked
|
| 4 |
+
// It checks blocks between a segment: example:
|
| 5 |
+
// real check point SAFE:
|
| 6 |
+
// pre check: (SAFE+1) -> (LATEST-32)
|
| 7 |
+
// It gets all pending blocks
|
| 8 |
+
// - Start cheking
|
| 9 |
+
|
| 10 |
+
import (
|
| 11 |
+
"context"
|
| 12 |
+
"errors"
|
| 13 |
+
"fmt"
|
| 14 |
+
"time"
|
| 15 |
+
|
| 16 |
+
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 17 |
+
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 18 |
+
"github.com/0xPolygonHermez/zkevm-node/synchronizer/common"
|
| 19 |
+
"github.com/jackc/pgx/v4"
|
| 20 |
+
)
|
| 21 |
+
|
| 22 |
+
var (
|
| 23 |
+
// ErrDeSync is an error that indicates that from the starting of verification to end something have been changed on state
|
| 24 |
+
ErrDeSync = errors.New("DeSync: a block hash is different from the state block hash")
|
| 25 |
+
)
|
| 26 |
+
|
| 27 |
+
// StatePreCheckInterfacer is an interface for the state
|
| 28 |
+
type StatePreCheckInterfacer interface {
|
| 29 |
+
GetUncheckedBlocks(ctx context.Context, fromBlockNumber uint64, toBlockNumber uint64, dbTx pgx.Tx) ([]*state.Block, error)
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
// PreCheckL1BlockHash is a struct that implements a checker of L1Block hash
|
| 33 |
+
type PreCheckL1BlockHash struct {
|
| 34 |
+
L1Client L1Requester
|
| 35 |
+
State StatePreCheckInterfacer
|
| 36 |
+
InitialSegmentBlockNumber SafeL1BlockNumberFetcher
|
| 37 |
+
EndSegmentBlockNumber SafeL1BlockNumberFetcher
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
// NewPreCheckL1BlockHash creates a new CheckL1BlockHash
|
| 41 |
+
func NewPreCheckL1BlockHash(l1Client L1Requester, state StatePreCheckInterfacer,
|
| 42 |
+
initial, end SafeL1BlockNumberFetcher) *PreCheckL1BlockHash {
|
| 43 |
+
return &PreCheckL1BlockHash{
|
| 44 |
+
L1Client: l1Client,
|
| 45 |
+
State: state,
|
| 46 |
+
InitialSegmentBlockNumber: initial,
|
| 47 |
+
EndSegmentBlockNumber: end,
|
| 48 |
+
}
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
// Name is a method that returns the name of the checker
|
| 52 |
+
func (p *PreCheckL1BlockHash) Name() string {
|
| 53 |
+
return logPrefix + ":memory_check: "
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
// Step is a method that checks the L1 block hash, run until all blocks are checked and returns
|
| 57 |
+
func (p *PreCheckL1BlockHash) Step(ctx context.Context) error {
|
| 58 |
+
from, err := p.InitialSegmentBlockNumber.GetSafeBlockNumber(ctx, p.L1Client)
|
| 59 |
+
if err != nil {
|
| 60 |
+
return err
|
| 61 |
+
}
|
| 62 |
+
to, err := p.EndSegmentBlockNumber.GetSafeBlockNumber(ctx, p.L1Client)
|
| 63 |
+
if err != nil {
|
| 64 |
+
return err
|
| 65 |
+
}
|
| 66 |
+
if from > to {
|
| 67 |
+
log.Warnf("%s: fromBlockNumber(%s) %d is greater than toBlockNumber(%s) %d, Check configuration", p.Name(), p.InitialSegmentBlockNumber.Description(), from, p.EndSegmentBlockNumber.Description(), to)
|
| 68 |
+
return nil
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
blocksToCheck, err := p.State.GetUncheckedBlocks(ctx, from, to, nil)
|
| 72 |
+
if err != nil {
|
| 73 |
+
log.Warnf("%s can't get unchecked blocks, so it discard the reorg error", p.Name())
|
| 74 |
+
return err
|
| 75 |
+
}
|
| 76 |
+
msg := fmt.Sprintf("%s: Checking blocks from (%s) %d to (%s) %d -> len(blocks)=%d", p.Name(), p.InitialSegmentBlockNumber.Description(), from, p.EndSegmentBlockNumber.Description(), to, len(blocksToCheck))
|
| 77 |
+
if len(blocksToCheck) == 0 {
|
| 78 |
+
log.Debugf(msg)
|
| 79 |
+
return nil
|
| 80 |
+
}
|
| 81 |
+
log.Infof(msg)
|
| 82 |
+
startTime := time.Now()
|
| 83 |
+
for _, block := range blocksToCheck {
|
| 84 |
+
// check block
|
| 85 |
+
err = CheckBlockHash(ctx, block, p.L1Client, p.Name())
|
| 86 |
+
if common.IsReorgError(err) {
|
| 87 |
+
// Double-check the state block that still is the same
|
| 88 |
+
log.Debugf("%s: Reorg detected at blockNumber: %d, checking that the block on State doesn't have change", p.Name(), block.BlockNumber)
|
| 89 |
+
isTheSame, errBlockIsTheSame := p.checkThatStateBlockIsTheSame(ctx, block)
|
| 90 |
+
if errBlockIsTheSame != nil {
|
| 91 |
+
log.Warnf("%s can't double-check that blockNumber %d haven't changed, so it discard the reorg error", p.Name(), block.BlockNumber)
|
| 92 |
+
return err
|
| 93 |
+
}
|
| 94 |
+
if !isTheSame {
|
| 95 |
+
log.Infof("%s: DeSync detected, blockNumber: %d is different now that when we started the check", p.Name(), block.BlockNumber)
|
| 96 |
+
return ErrDeSync
|
| 97 |
+
}
|
| 98 |
+
log.Infof("%s: Reorg detected and verified the state block, blockNumber: %d", p.Name(), block.BlockNumber)
|
| 99 |
+
return err
|
| 100 |
+
}
|
| 101 |
+
if err != nil {
|
| 102 |
+
return err
|
| 103 |
+
}
|
| 104 |
+
}
|
| 105 |
+
elapsed := time.Since(startTime)
|
| 106 |
+
log.Infof("%s: Checked blocks from (%s) %d to (%s) %d -> len(blocks):%d elapsed: %s", p.Name(), p.InitialSegmentBlockNumber.Description(), from, p.EndSegmentBlockNumber.Description(), to, len(blocksToCheck), elapsed.String())
|
| 107 |
+
|
| 108 |
+
return nil
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
// CheckBlockHash is a method that checks the L1 block hash
|
| 112 |
+
// returns true if is the same
|
| 113 |
+
func (p *PreCheckL1BlockHash) checkThatStateBlockIsTheSame(ctx context.Context, block *state.Block) (bool, error) {
|
| 114 |
+
blocks, err := p.State.GetUncheckedBlocks(ctx, block.BlockNumber, block.BlockNumber, nil)
|
| 115 |
+
if err != nil {
|
| 116 |
+
log.Warnf("%s: Fails to get blockNumber %d in state .Err:%s", p.Name(), block.BlockNumber, err.Error())
|
| 117 |
+
return false, err
|
| 118 |
+
}
|
| 119 |
+
if len(blocks) == 0 {
|
| 120 |
+
// The block is checked or deleted, so it is not the same
|
| 121 |
+
log.Debugf("%s: The blockNumber %d is no longer in the state (or checked or deleted)", p.Name(), block.BlockNumber)
|
| 122 |
+
return false, nil
|
| 123 |
+
}
|
| 124 |
+
stateBlock := blocks[0]
|
| 125 |
+
if stateBlock.BlockNumber != block.BlockNumber {
|
| 126 |
+
msg := fmt.Sprintf("%s: The blockNumber returned by state %d is different from the state blockNumber %d",
|
| 127 |
+
p.Name(), block.BlockNumber, stateBlock.BlockNumber)
|
| 128 |
+
log.Warn(msg)
|
| 129 |
+
return false, fmt.Errorf(msg)
|
| 130 |
+
}
|
| 131 |
+
if stateBlock.BlockHash != block.BlockHash {
|
| 132 |
+
msg := fmt.Sprintf("%s: The blockNumber %d differs the hash checked %s from current in state %s",
|
| 133 |
+
p.Name(), block.BlockNumber, block.BlockHash.String(), stateBlock.BlockHash.String())
|
| 134 |
+
log.Warn(msg)
|
| 135 |
+
return false, nil
|
| 136 |
+
}
|
| 137 |
+
// The block is the same
|
| 138 |
+
return true, nil
|
| 139 |
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package l1_check_block_test
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"context"
|
| 5 |
+
"math/big"
|
| 6 |
+
"testing"
|
| 7 |
+
|
| 8 |
+
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 9 |
+
commonsync "github.com/0xPolygonHermez/zkevm-node/synchronizer/common"
|
| 10 |
+
"github.com/0xPolygonHermez/zkevm-node/synchronizer/l1_check_block"
|
| 11 |
+
mock_l1_check_block "github.com/0xPolygonHermez/zkevm-node/synchronizer/l1_check_block/mocks"
|
| 12 |
+
"github.com/ethereum/go-ethereum/common"
|
| 13 |
+
"github.com/ethereum/go-ethereum/core/types"
|
| 14 |
+
"github.com/stretchr/testify/require"
|
| 15 |
+
)
|
| 16 |
+
|
| 17 |
+
type testPreCheckData struct {
|
| 18 |
+
sut *l1_check_block.PreCheckL1BlockHash
|
| 19 |
+
mockL1Client *mock_l1_check_block.L1Requester
|
| 20 |
+
mockState *mock_l1_check_block.StatePreCheckInterfacer
|
| 21 |
+
mockInitialFetch *mock_l1_check_block.SafeL1BlockNumberFetcher
|
| 22 |
+
mockEndFetch *mock_l1_check_block.SafeL1BlockNumberFetcher
|
| 23 |
+
ctx context.Context
|
| 24 |
+
stateBlocks []*state.Block
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
func newPreCheckData(t *testing.T) *testPreCheckData {
|
| 28 |
+
mockL1Client := mock_l1_check_block.NewL1Requester(t)
|
| 29 |
+
mockState := mock_l1_check_block.NewStatePreCheckInterfacer(t)
|
| 30 |
+
mockInitialFetch := mock_l1_check_block.NewSafeL1BlockNumberFetcher(t)
|
| 31 |
+
mockEndFetch := mock_l1_check_block.NewSafeL1BlockNumberFetcher(t)
|
| 32 |
+
sut := l1_check_block.NewPreCheckL1BlockHash(mockL1Client, mockState, mockInitialFetch, mockEndFetch)
|
| 33 |
+
return &testPreCheckData{
|
| 34 |
+
sut: sut,
|
| 35 |
+
mockL1Client: mockL1Client,
|
| 36 |
+
mockState: mockState,
|
| 37 |
+
mockInitialFetch: mockInitialFetch,
|
| 38 |
+
mockEndFetch: mockEndFetch,
|
| 39 |
+
ctx: context.Background(),
|
| 40 |
+
stateBlocks: []*state.Block{
|
| 41 |
+
{
|
| 42 |
+
BlockNumber: 1234,
|
| 43 |
+
BlockHash: common.HexToHash("0xd77dd3a9ee6f9202ca5a75024b7d9cbd3d7436b2910d450f88c261c0089c0cd9"),
|
| 44 |
+
},
|
| 45 |
+
{
|
| 46 |
+
BlockNumber: 1237,
|
| 47 |
+
BlockHash: common.HexToHash("0x8faffac37f561c18917c33ff3540262ecfbe11a367b4e1c48181326cd8ba347f"),
|
| 48 |
+
},
|
| 49 |
+
},
|
| 50 |
+
}
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
// If from > to, it ignore because there are no blocks to check
|
| 54 |
+
func TestPreCheckL1BlockFromGreaterThanTo(t *testing.T) {
|
| 55 |
+
data := newPreCheckData(t)
|
| 56 |
+
data.mockInitialFetch.EXPECT().Description().Return("initial")
|
| 57 |
+
data.mockEndFetch.EXPECT().Description().Return("end")
|
| 58 |
+
data.mockInitialFetch.EXPECT().GetSafeBlockNumber(data.ctx, data.mockL1Client).Return(uint64(1234), nil)
|
| 59 |
+
data.mockEndFetch.EXPECT().GetSafeBlockNumber(data.ctx, data.mockL1Client).Return(uint64(1230), nil)
|
| 60 |
+
|
| 61 |
+
res := data.sut.Step(data.ctx)
|
| 62 |
+
require.NoError(t, res)
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
// No blocks on state -> nothing to do
|
| 66 |
+
func TestPreCheckL1BlockNoBlocksOnState(t *testing.T) {
|
| 67 |
+
data := newPreCheckData(t)
|
| 68 |
+
data.mockInitialFetch.EXPECT().Description().Return("initial")
|
| 69 |
+
data.mockEndFetch.EXPECT().Description().Return("end")
|
| 70 |
+
data.mockInitialFetch.EXPECT().GetSafeBlockNumber(data.ctx, data.mockL1Client).Return(uint64(1234), nil)
|
| 71 |
+
data.mockEndFetch.EXPECT().GetSafeBlockNumber(data.ctx, data.mockL1Client).Return(uint64(1250), nil)
|
| 72 |
+
data.mockState.EXPECT().GetUncheckedBlocks(data.ctx, uint64(1234), uint64(1250), nil).Return(nil, nil)
|
| 73 |
+
|
| 74 |
+
res := data.sut.Step(data.ctx)
|
| 75 |
+
require.NoError(t, res)
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
func TestPreCheckL1BlockBlocksMatch(t *testing.T) {
|
| 79 |
+
data := newPreCheckData(t)
|
| 80 |
+
data.mockInitialFetch.EXPECT().Description().Return("initial")
|
| 81 |
+
data.mockEndFetch.EXPECT().Description().Return("end")
|
| 82 |
+
data.mockInitialFetch.EXPECT().GetSafeBlockNumber(data.ctx, data.mockL1Client).Return(uint64(1234), nil)
|
| 83 |
+
data.mockEndFetch.EXPECT().GetSafeBlockNumber(data.ctx, data.mockL1Client).Return(uint64(1250), nil)
|
| 84 |
+
data.mockState.EXPECT().GetUncheckedBlocks(data.ctx, uint64(1234), uint64(1250), nil).Return(data.stateBlocks, nil)
|
| 85 |
+
l1Block1 := &types.Header{
|
| 86 |
+
Number: big.NewInt(int64(data.stateBlocks[0].BlockNumber)),
|
| 87 |
+
}
|
| 88 |
+
data.mockL1Client.EXPECT().HeaderByNumber(data.ctx, big.NewInt(int64(data.stateBlocks[0].BlockNumber))).Return(l1Block1, nil)
|
| 89 |
+
l1Block2 := &types.Header{
|
| 90 |
+
Number: big.NewInt(int64(data.stateBlocks[1].BlockNumber)),
|
| 91 |
+
}
|
| 92 |
+
data.mockL1Client.EXPECT().HeaderByNumber(data.ctx, big.NewInt(int64(data.stateBlocks[1].BlockNumber))).Return(l1Block2, nil)
|
| 93 |
+
//data.mockState.EXPECT().GetUncheckedBlocks(data.ctx, uint64(1237), uint64(1237), nil).Return(data.stateBlocks[0:1], nil)
|
| 94 |
+
|
| 95 |
+
res := data.sut.Step(data.ctx)
|
| 96 |
+
require.NoError(t, res)
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
func TestPreCheckL1BlockBlocksMismatch(t *testing.T) {
|
| 100 |
+
data := newPreCheckData(t)
|
| 101 |
+
data.mockInitialFetch.EXPECT().Description().Return("initial")
|
| 102 |
+
data.mockEndFetch.EXPECT().Description().Return("end")
|
| 103 |
+
data.mockInitialFetch.EXPECT().GetSafeBlockNumber(data.ctx, data.mockL1Client).Return(uint64(1234), nil)
|
| 104 |
+
data.mockEndFetch.EXPECT().GetSafeBlockNumber(data.ctx, data.mockL1Client).Return(uint64(1250), nil)
|
| 105 |
+
data.stateBlocks[1].BlockHash = common.HexToHash("0x12345678901234567890123456789012345678901234567890")
|
| 106 |
+
data.mockState.EXPECT().GetUncheckedBlocks(data.ctx, uint64(1234), uint64(1250), nil).Return(data.stateBlocks, nil)
|
| 107 |
+
l1Block1 := &types.Header{
|
| 108 |
+
Number: big.NewInt(int64(data.stateBlocks[0].BlockNumber)),
|
| 109 |
+
}
|
| 110 |
+
data.mockL1Client.EXPECT().HeaderByNumber(data.ctx, big.NewInt(int64(data.stateBlocks[0].BlockNumber))).Return(l1Block1, nil)
|
| 111 |
+
l1Block2 := &types.Header{
|
| 112 |
+
Number: big.NewInt(int64(data.stateBlocks[1].BlockNumber)),
|
| 113 |
+
}
|
| 114 |
+
data.mockL1Client.EXPECT().HeaderByNumber(data.ctx, big.NewInt(int64(data.stateBlocks[1].BlockNumber))).Return(l1Block2, nil)
|
| 115 |
+
data.mockState.EXPECT().GetUncheckedBlocks(data.ctx, uint64(1237), uint64(1237), nil).Return(data.stateBlocks[1:2], nil)
|
| 116 |
+
|
| 117 |
+
res := data.sut.Step(data.ctx)
|
| 118 |
+
require.Error(t, res)
|
| 119 |
+
resErr, ok := res.(*commonsync.ReorgError)
|
| 120 |
+
require.True(t, ok, "The error must be ReorgError")
|
| 121 |
+
require.Equal(t, uint64(1237), resErr.BlockNumber)
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
func TestPreCheckL1BlockBlocksMismatchButIsNoLongerInState(t *testing.T) {
|
| 125 |
+
data := newPreCheckData(t)
|
| 126 |
+
data.mockInitialFetch.EXPECT().Description().Return("initial")
|
| 127 |
+
data.mockEndFetch.EXPECT().Description().Return("end")
|
| 128 |
+
data.mockInitialFetch.EXPECT().GetSafeBlockNumber(data.ctx, data.mockL1Client).Return(uint64(1234), nil)
|
| 129 |
+
data.mockEndFetch.EXPECT().GetSafeBlockNumber(data.ctx, data.mockL1Client).Return(uint64(1250), nil)
|
| 130 |
+
data.stateBlocks[1].BlockHash = common.HexToHash("0x12345678901234567890123456789012345678901234567890")
|
| 131 |
+
data.mockState.EXPECT().GetUncheckedBlocks(data.ctx, uint64(1234), uint64(1250), nil).Return(data.stateBlocks, nil)
|
| 132 |
+
l1Block1 := &types.Header{
|
| 133 |
+
Number: big.NewInt(int64(data.stateBlocks[0].BlockNumber)),
|
| 134 |
+
}
|
| 135 |
+
data.mockL1Client.EXPECT().HeaderByNumber(data.ctx, big.NewInt(int64(data.stateBlocks[0].BlockNumber))).Return(l1Block1, nil)
|
| 136 |
+
l1Block2 := &types.Header{
|
| 137 |
+
Number: big.NewInt(int64(data.stateBlocks[1].BlockNumber)),
|
| 138 |
+
}
|
| 139 |
+
data.mockL1Client.EXPECT().HeaderByNumber(data.ctx, big.NewInt(int64(data.stateBlocks[1].BlockNumber))).Return(l1Block2, nil)
|
| 140 |
+
data.mockState.EXPECT().GetUncheckedBlocks(data.ctx, uint64(1237), uint64(1237), nil).Return(nil, nil)
|
| 141 |
+
|
| 142 |
+
res := data.sut.Step(data.ctx)
|
| 143 |
+
require.ErrorIs(t, res, l1_check_block.ErrDeSync)
|
| 144 |
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package l1_check_block
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"context"
|
| 5 |
+
"fmt"
|
| 6 |
+
"math/big"
|
| 7 |
+
|
| 8 |
+
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 9 |
+
"github.com/ethereum/go-ethereum/rpc"
|
| 10 |
+
)
|
| 11 |
+
|
| 12 |
+
// L1BlockPoint is an enum that represents the point of the L1 block
|
| 13 |
+
type L1BlockPoint int
|
| 14 |
+
|
| 15 |
+
const (
|
| 16 |
+
// FinalizedBlockNumber is the finalized block number
|
| 17 |
+
FinalizedBlockNumber L1BlockPoint = 3
|
| 18 |
+
// SafeBlockNumber is the safe block number
|
| 19 |
+
SafeBlockNumber L1BlockPoint = 2
|
| 20 |
+
// PendingBlockNumber is the pending block number
|
| 21 |
+
PendingBlockNumber L1BlockPoint = 1
|
| 22 |
+
// LastBlockNumber is the last block number
|
| 23 |
+
LastBlockNumber L1BlockPoint = 0
|
| 24 |
+
)
|
| 25 |
+
|
| 26 |
+
// ToString converts a L1BlockPoint to a string
|
| 27 |
+
func (v L1BlockPoint) ToString() string {
|
| 28 |
+
switch v {
|
| 29 |
+
case FinalizedBlockNumber:
|
| 30 |
+
return "finalized"
|
| 31 |
+
case SafeBlockNumber:
|
| 32 |
+
return "safe"
|
| 33 |
+
case PendingBlockNumber:
|
| 34 |
+
return "pending"
|
| 35 |
+
case LastBlockNumber:
|
| 36 |
+
return "latest"
|
| 37 |
+
}
|
| 38 |
+
return "Unknown"
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
// StringToL1BlockPoint converts a string to a L1BlockPoint
|
| 42 |
+
func StringToL1BlockPoint(s string) L1BlockPoint {
|
| 43 |
+
switch s {
|
| 44 |
+
case "finalized":
|
| 45 |
+
return FinalizedBlockNumber
|
| 46 |
+
case "safe":
|
| 47 |
+
return SafeBlockNumber
|
| 48 |
+
case "pending":
|
| 49 |
+
return PendingBlockNumber
|
| 50 |
+
case "latest":
|
| 51 |
+
return LastBlockNumber
|
| 52 |
+
default:
|
| 53 |
+
return FinalizedBlockNumber
|
| 54 |
+
}
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
// ToGethRequest converts a L1BlockPoint to a big.Int used for request to GETH
|
| 58 |
+
func (v L1BlockPoint) ToGethRequest() *big.Int {
|
| 59 |
+
switch v {
|
| 60 |
+
case FinalizedBlockNumber:
|
| 61 |
+
return big.NewInt(int64(rpc.FinalizedBlockNumber))
|
| 62 |
+
case PendingBlockNumber:
|
| 63 |
+
return big.NewInt(int64(rpc.PendingBlockNumber))
|
| 64 |
+
case SafeBlockNumber:
|
| 65 |
+
return big.NewInt(int64(rpc.SafeBlockNumber))
|
| 66 |
+
case LastBlockNumber:
|
| 67 |
+
return nil
|
| 68 |
+
}
|
| 69 |
+
return big.NewInt(int64(v))
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
// SafeL1BlockNumberFetch is a struct that implements a safe L1 block number fetch
|
| 73 |
+
type SafeL1BlockNumberFetch struct {
|
| 74 |
+
// SafeBlockPoint is the block number that is reference to l1 Block
|
| 75 |
+
SafeBlockPoint L1BlockPoint
|
| 76 |
+
// Offset is a vaule add to the L1 block
|
| 77 |
+
Offset int
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
// NewSafeL1BlockNumberFetch creates a new SafeL1BlockNumberFetch
|
| 81 |
+
func NewSafeL1BlockNumberFetch(safeBlockPoint L1BlockPoint, offset int) *SafeL1BlockNumberFetch {
|
| 82 |
+
return &SafeL1BlockNumberFetch{
|
| 83 |
+
SafeBlockPoint: safeBlockPoint,
|
| 84 |
+
Offset: offset,
|
| 85 |
+
}
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
// Description returns a string representation of SafeL1BlockNumberFetch
|
| 89 |
+
func (p *SafeL1BlockNumberFetch) Description() string {
|
| 90 |
+
return fmt.Sprintf("%s/%d", p.SafeBlockPoint.ToString(), p.Offset)
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
// GetSafeBlockNumber gets the safe block number from L1
|
| 94 |
+
func (p *SafeL1BlockNumberFetch) GetSafeBlockNumber(ctx context.Context, requester L1Requester) (uint64, error) {
|
| 95 |
+
l1SafePointBlock, err := requester.HeaderByNumber(ctx, p.SafeBlockPoint.ToGethRequest())
|
| 96 |
+
if err != nil {
|
| 97 |
+
log.Errorf("%s: Error getting L1 block %d. err: %s", logPrefix, p.String(), err.Error())
|
| 98 |
+
return uint64(0), err
|
| 99 |
+
}
|
| 100 |
+
result := l1SafePointBlock.Number.Uint64()
|
| 101 |
+
if p.Offset < 0 {
|
| 102 |
+
if result < uint64(-p.Offset) {
|
| 103 |
+
result = 0
|
| 104 |
+
} else {
|
| 105 |
+
result += uint64(p.Offset)
|
| 106 |
+
}
|
| 107 |
+
} else {
|
| 108 |
+
result = l1SafePointBlock.Number.Uint64() + uint64(p.Offset)
|
| 109 |
+
}
|
| 110 |
+
if p.SafeBlockPoint == LastBlockNumber {
|
| 111 |
+
result = min(result, l1SafePointBlock.Number.Uint64())
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
return result, nil
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
// String returns a string representation of SafeL1BlockNumberFetch
|
| 118 |
+
func (p *SafeL1BlockNumberFetch) String() string {
|
| 119 |
+
return fmt.Sprintf("SafeBlockPoint: %s, Offset: %d", p.SafeBlockPoint.ToString(), p.Offset)
|
| 120 |
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package l1_check_block_test
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"context"
|
| 5 |
+
"math/big"
|
| 6 |
+
"testing"
|
| 7 |
+
|
| 8 |
+
"github.com/0xPolygonHermez/zkevm-node/synchronizer/l1_check_block"
|
| 9 |
+
mock_l1_check_block "github.com/0xPolygonHermez/zkevm-node/synchronizer/l1_check_block/mocks"
|
| 10 |
+
"github.com/ethereum/go-ethereum/core/types"
|
| 11 |
+
"github.com/ethereum/go-ethereum/rpc"
|
| 12 |
+
"github.com/stretchr/testify/assert"
|
| 13 |
+
"github.com/stretchr/testify/mock"
|
| 14 |
+
)
|
| 15 |
+
|
| 16 |
+
func TestGetSafeBlockNumber(t *testing.T) {
|
| 17 |
+
ctx := context.Background()
|
| 18 |
+
mockRequester := mock_l1_check_block.NewL1Requester(t)
|
| 19 |
+
//safeBlockPoint := big.NewInt(50)
|
| 20 |
+
offset := 10
|
| 21 |
+
safeL1Block := l1_check_block.NewSafeL1BlockNumberFetch(l1_check_block.StringToL1BlockPoint("safe"), offset)
|
| 22 |
+
|
| 23 |
+
mockRequester.EXPECT().HeaderByNumber(ctx, mock.Anything).Return(&types.Header{
|
| 24 |
+
Number: big.NewInt(100),
|
| 25 |
+
}, nil)
|
| 26 |
+
blockNumber, err := safeL1Block.GetSafeBlockNumber(ctx, mockRequester)
|
| 27 |
+
assert.NoError(t, err)
|
| 28 |
+
expectedBlockNumber := uint64(100 + offset)
|
| 29 |
+
assert.Equal(t, expectedBlockNumber, blockNumber)
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
func TestGetSafeBlockNumberMutliplesCases(t *testing.T) {
|
| 33 |
+
tests := []struct {
|
| 34 |
+
name string
|
| 35 |
+
blockPoint string
|
| 36 |
+
offset int
|
| 37 |
+
l1ReturnBlockNumber uint64
|
| 38 |
+
expectedCallToGeth *big.Int
|
| 39 |
+
expectedBlockNumber uint64
|
| 40 |
+
}{
|
| 41 |
+
{
|
| 42 |
+
name: "SafeBlockNumber+10",
|
| 43 |
+
blockPoint: "safe",
|
| 44 |
+
offset: 10,
|
| 45 |
+
l1ReturnBlockNumber: 100,
|
| 46 |
+
expectedCallToGeth: big.NewInt(int64(rpc.SafeBlockNumber)),
|
| 47 |
+
expectedBlockNumber: 110,
|
| 48 |
+
},
|
| 49 |
+
{
|
| 50 |
+
name: "FinalizedBlockNumber+10",
|
| 51 |
+
blockPoint: "finalized",
|
| 52 |
+
offset: 10,
|
| 53 |
+
l1ReturnBlockNumber: 100,
|
| 54 |
+
expectedCallToGeth: big.NewInt(int64(rpc.FinalizedBlockNumber)),
|
| 55 |
+
expectedBlockNumber: 110,
|
| 56 |
+
},
|
| 57 |
+
{
|
| 58 |
+
name: "PendingBlockNumber+10",
|
| 59 |
+
blockPoint: "pending",
|
| 60 |
+
offset: 10,
|
| 61 |
+
l1ReturnBlockNumber: 100,
|
| 62 |
+
expectedCallToGeth: big.NewInt(int64(rpc.PendingBlockNumber)),
|
| 63 |
+
expectedBlockNumber: 110,
|
| 64 |
+
},
|
| 65 |
+
{
|
| 66 |
+
name: "LastBlockNumber+10, can't add 10 to latest block number. So must return latest block number and ignore positive offset",
|
| 67 |
+
blockPoint: "latest",
|
| 68 |
+
offset: 10,
|
| 69 |
+
l1ReturnBlockNumber: 100,
|
| 70 |
+
expectedCallToGeth: nil,
|
| 71 |
+
expectedBlockNumber: 100,
|
| 72 |
+
},
|
| 73 |
+
{
|
| 74 |
+
name: "FinalizedBlockNumber-1000. negative blockNumbers are not welcome. So must return 0",
|
| 75 |
+
blockPoint: "finalized",
|
| 76 |
+
offset: -1000,
|
| 77 |
+
l1ReturnBlockNumber: 100,
|
| 78 |
+
expectedCallToGeth: big.NewInt(int64(rpc.FinalizedBlockNumber)),
|
| 79 |
+
expectedBlockNumber: 0,
|
| 80 |
+
},
|
| 81 |
+
{
|
| 82 |
+
name: "FinalizedBlockNumber(1000)-1000. is 0 ",
|
| 83 |
+
blockPoint: "finalized",
|
| 84 |
+
offset: -1000,
|
| 85 |
+
l1ReturnBlockNumber: 1000,
|
| 86 |
+
expectedCallToGeth: big.NewInt(int64(rpc.FinalizedBlockNumber)),
|
| 87 |
+
expectedBlockNumber: 0,
|
| 88 |
+
},
|
| 89 |
+
{
|
| 90 |
+
name: "FinalizedBlockNumber(1001)-1000. is 1 ",
|
| 91 |
+
blockPoint: "finalized",
|
| 92 |
+
offset: -1000,
|
| 93 |
+
l1ReturnBlockNumber: 1001,
|
| 94 |
+
expectedCallToGeth: big.NewInt(int64(rpc.FinalizedBlockNumber)),
|
| 95 |
+
expectedBlockNumber: 1,
|
| 96 |
+
},
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
for _, tt := range tests {
|
| 100 |
+
t.Run(tt.name, func(t *testing.T) {
|
| 101 |
+
ctx := context.Background()
|
| 102 |
+
mockRequester := mock_l1_check_block.NewL1Requester(t)
|
| 103 |
+
safeL1Block := l1_check_block.NewSafeL1BlockNumberFetch(l1_check_block.StringToL1BlockPoint(tt.blockPoint), tt.offset)
|
| 104 |
+
|
| 105 |
+
mockRequester.EXPECT().HeaderByNumber(ctx, tt.expectedCallToGeth).Return(&types.Header{
|
| 106 |
+
Number: big.NewInt(int64(tt.l1ReturnBlockNumber)),
|
| 107 |
+
}, nil)
|
| 108 |
+
blockNumber, err := safeL1Block.GetSafeBlockNumber(ctx, mockRequester)
|
| 109 |
+
assert.NoError(t, err)
|
| 110 |
+
assert.Equal(t, tt.expectedBlockNumber, blockNumber)
|
| 111 |
+
})
|
| 112 |
+
}
|
| 113 |
+
}
|
|
@@ -3,6 +3,7 @@
|
|
| 3 |
import (
|
| 4 |
"context"
|
| 5 |
"errors"
|
|
|
|
| 6 |
"sync"
|
| 7 |
"time"
|
| 8 |
|
|
@@ -22,7 +24,6 @@
|
|
| 22 |
errContextCanceled = errors.New("consumer:context canceled")
|
| 23 |
errConsumerStopped = errors.New("consumer:stopped by request")
|
| 24 |
errConsumerStoppedBecauseIsSynchronized = errors.New("consumer:stopped because is synchronized")
|
| 25 |
-
errL1Reorg = errors.New("consumer: L1 reorg detected")
|
| 26 |
errConsumerAndProducerDesynchronized = errors.New("consumer: consumer and producer are desynchronized")
|
| 27 |
)
|
| 28 |
|
|
@@ -155,13 +156,12 @@
|
|
| 155 |
}
|
| 156 |
if cachedBlock.BlockNumber == rollupInfo.previousBlockOfRange.NumberU64() {
|
| 157 |
if cachedBlock.BlockHash != rollupInfo.previousBlockOfRange.Hash() {
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
log.Errorf("consumer: Previous block %d parentHash is not the same", cachedBlock.BlockNumber)
|
| 163 |
-
return errL1Reorg
|
| 164 |
}
|
|
|
|
| 165 |
log.Infof("consumer: Verified previous block %d not the same: OK", cachedBlock.BlockNumber)
|
| 166 |
}
|
| 167 |
return nil
|
|
|
|
| 3 |
import (
|
| 4 |
"context"
|
| 5 |
"errors"
|
| 6 |
+
"fmt"
|
| 7 |
"sync"
|
| 8 |
"time"
|
| 9 |
|
|
|
|
| 24 |
errContextCanceled = errors.New("consumer:context canceled")
|
| 25 |
errConsumerStopped = errors.New("consumer:stopped by request")
|
| 26 |
errConsumerStoppedBecauseIsSynchronized = errors.New("consumer:stopped because is synchronized")
|
|
|
|
| 27 |
errConsumerAndProducerDesynchronized = errors.New("consumer: consumer and producer are desynchronized")
|
| 28 |
)
|
| 29 |
|
|
|
|
| 156 |
}
|
| 157 |
if cachedBlock.BlockNumber == rollupInfo.previousBlockOfRange.NumberU64() {
|
| 158 |
if cachedBlock.BlockHash != rollupInfo.previousBlockOfRange.Hash() {
|
| 159 |
+
err := fmt.Errorf("consumer: Previous block %d hash is not the same. state.Hash:%s != l1.Hash:%s",
|
| 160 |
+
cachedBlock.BlockNumber, cachedBlock.BlockHash, rollupInfo.previousBlockOfRange.Hash())
|
| 161 |
+
log.Errorf(err.Error())
|
| 162 |
+
return syncCommon.NewReorgError(cachedBlock.BlockNumber, err)
|
|
|
|
|
|
|
| 163 |
}
|
| 164 |
+
|
| 165 |
log.Infof("consumer: Verified previous block %d not the same: OK", cachedBlock.BlockNumber)
|
| 166 |
}
|
| 167 |
return nil
|
|
@@ -31,7 +31,7 @@
|
|
| 31 |
GlobalExitRootManagerAddr: common.HexToAddress("0x8A791620dd6260079BF849Dc5567aDC3F2FdC318"),
|
| 32 |
}
|
| 33 |
|
| 34 |
-
ethermanClient, err := etherman.NewClient(cfg, l1Config)
|
| 35 |
require.NoError(t, err)
|
| 36 |
worker := newWorker(ethermanClient)
|
| 37 |
ch := make(chan responseRollupInfoByBlockRange)
|
|
|
|
| 31 |
GlobalExitRootManagerAddr: common.HexToAddress("0x8A791620dd6260079BF849Dc5567aDC3F2FdC318"),
|
| 32 |
}
|
| 33 |
|
| 34 |
+
ethermanClient, err := etherman.NewClient(cfg, l1Config, nil, nil)
|
| 35 |
require.NoError(t, err)
|
| 36 |
worker := newWorker(ethermanClient)
|
| 37 |
ch := make(chan responseRollupInfoByBlockRange)
|
|
@@ -171,6 +171,10 @@
|
|
| 171 |
|
| 172 |
// ProcessTrustedBatch processes a trusted batch and return the new state
|
| 173 |
func (s *ProcessorTrustedBatchSync) ProcessTrustedBatch(ctx context.Context, trustedBatch *types.Batch, status TrustedState, dbTx pgx.Tx, debugPrefix string) (*TrustedState, error) {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 174 |
log.Debugf("%s Processing trusted batch: %v", debugPrefix, trustedBatch.Number)
|
| 175 |
stateCurrentBatch, statePreviousBatch := s.GetCurrentAndPreviousBatchFromCache(&status)
|
| 176 |
if s.l1SyncChecker != nil {
|
|
@@ -374,7 +378,9 @@
|
|
| 374 |
result.OldAccInputHash = statePreviousBatch.AccInputHash
|
| 375 |
result.Now = s.timeProvider.Now()
|
| 376 |
result.DebugPrefix = fmt.Sprintf("%s mode %s:", debugPrefix, result.Mode)
|
| 377 |
-
|
|
|
|
|
|
|
| 378 |
if isTrustedBatchEmptyAndClosed(trustedNodeBatch) {
|
| 379 |
if s.Cfg.AcceptEmptyClosedBatches {
|
| 380 |
log.Infof("%s Batch %v: TrustedBatch Empty and closed, accepted due configuration", result.DebugPrefix, trustedNodeBatch.Number)
|
|
|
|
| 171 |
|
| 172 |
// ProcessTrustedBatch processes a trusted batch and return the new state
|
| 173 |
func (s *ProcessorTrustedBatchSync) ProcessTrustedBatch(ctx context.Context, trustedBatch *types.Batch, status TrustedState, dbTx pgx.Tx, debugPrefix string) (*TrustedState, error) {
|
| 174 |
+
if trustedBatch == nil {
|
| 175 |
+
log.Errorf("%s trustedBatch is nil, it never should be nil", debugPrefix)
|
| 176 |
+
return nil, fmt.Errorf("%s trustedBatch is nil, it never should be nil", debugPrefix)
|
| 177 |
+
}
|
| 178 |
log.Debugf("%s Processing trusted batch: %v", debugPrefix, trustedBatch.Number)
|
| 179 |
stateCurrentBatch, statePreviousBatch := s.GetCurrentAndPreviousBatchFromCache(&status)
|
| 180 |
if s.l1SyncChecker != nil {
|
|
|
|
| 378 |
result.OldAccInputHash = statePreviousBatch.AccInputHash
|
| 379 |
result.Now = s.timeProvider.Now()
|
| 380 |
result.DebugPrefix = fmt.Sprintf("%s mode %s:", debugPrefix, result.Mode)
|
| 381 |
+
if result.BatchMustBeClosed {
|
| 382 |
+
result.DebugPrefix += " (must_be_closed)"
|
| 383 |
+
}
|
| 384 |
if isTrustedBatchEmptyAndClosed(trustedNodeBatch) {
|
| 385 |
if s.Cfg.AcceptEmptyClosedBatches {
|
| 386 |
log.Infof("%s Batch %v: TrustedBatch Empty and closed, accepted due configuration", result.DebugPrefix, trustedNodeBatch.Number)
|
|
@@ -0,0 +1,117 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package test_l2_shared
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"context"
|
| 5 |
+
"math/big"
|
| 6 |
+
"testing"
|
| 7 |
+
|
| 8 |
+
"github.com/0xPolygonHermez/zkevm-node/jsonrpc/types"
|
| 9 |
+
"github.com/0xPolygonHermez/zkevm-node/state"
|
| 10 |
+
"github.com/0xPolygonHermez/zkevm-node/synchronizer/common"
|
| 11 |
+
mock_syncinterfaces "github.com/0xPolygonHermez/zkevm-node/synchronizer/common/syncinterfaces/mocks"
|
| 12 |
+
"github.com/0xPolygonHermez/zkevm-node/synchronizer/l2_sync/l2_shared"
|
| 13 |
+
l2sharedmocks "github.com/0xPolygonHermez/zkevm-node/synchronizer/l2_sync/l2_shared/mocks"
|
| 14 |
+
syncMocks "github.com/0xPolygonHermez/zkevm-node/synchronizer/mocks"
|
| 15 |
+
"github.com/stretchr/testify/mock"
|
| 16 |
+
"github.com/stretchr/testify/require"
|
| 17 |
+
)
|
| 18 |
+
|
| 19 |
+
type testDataTrustedBatchRetrieve struct {
|
| 20 |
+
mockBatchProcessor *l2sharedmocks.BatchProcessor
|
| 21 |
+
mockZkEVMClient *mock_syncinterfaces.ZKEVMClientTrustedBatchesGetter
|
| 22 |
+
mockState *l2sharedmocks.StateInterface
|
| 23 |
+
mockSync *mock_syncinterfaces.SynchronizerFlushIDManager
|
| 24 |
+
mockTimer *common.MockTimerProvider
|
| 25 |
+
mockDbTx *syncMocks.DbTxMock
|
| 26 |
+
TrustedStateMngr *l2_shared.TrustedStateManager
|
| 27 |
+
sut *l2_shared.TrustedBatchesRetrieve
|
| 28 |
+
ctx context.Context
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
func newTestDataTrustedBatchRetrieve(t *testing.T) *testDataTrustedBatchRetrieve {
|
| 32 |
+
mockBatchProcessor := l2sharedmocks.NewBatchProcessor(t)
|
| 33 |
+
mockZkEVMClient := mock_syncinterfaces.NewZKEVMClientTrustedBatchesGetter(t)
|
| 34 |
+
mockState := l2sharedmocks.NewStateInterface(t)
|
| 35 |
+
mockSync := mock_syncinterfaces.NewSynchronizerFlushIDManager(t)
|
| 36 |
+
mockTimer := &common.MockTimerProvider{}
|
| 37 |
+
mockDbTx := syncMocks.NewDbTxMock(t)
|
| 38 |
+
TrustedStateMngr := l2_shared.NewTrustedStateManager(mockTimer, 0)
|
| 39 |
+
sut := l2_shared.NewTrustedBatchesRetrieve(mockBatchProcessor, mockZkEVMClient, mockState, mockSync, *TrustedStateMngr)
|
| 40 |
+
ctx := context.TODO()
|
| 41 |
+
return &testDataTrustedBatchRetrieve{
|
| 42 |
+
mockBatchProcessor: mockBatchProcessor,
|
| 43 |
+
mockZkEVMClient: mockZkEVMClient,
|
| 44 |
+
mockState: mockState,
|
| 45 |
+
mockSync: mockSync,
|
| 46 |
+
mockTimer: mockTimer,
|
| 47 |
+
mockDbTx: mockDbTx,
|
| 48 |
+
TrustedStateMngr: TrustedStateMngr,
|
| 49 |
+
sut: sut,
|
| 50 |
+
ctx: ctx,
|
| 51 |
+
}
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
const (
|
| 55 |
+
closedBatch = true
|
| 56 |
+
notClosedBatch = false
|
| 57 |
+
)
|
| 58 |
+
|
| 59 |
+
// This test must do from 100 to 104.
|
| 60 |
+
// But the batch 100 is open on TrustedNode so it stop processing
|
| 61 |
+
func TestSyncTrustedBatchesToFromStopAfterFirstWIPBatch(t *testing.T) {
|
| 62 |
+
data := newTestDataTrustedBatchRetrieve(t)
|
| 63 |
+
data.mockZkEVMClient.EXPECT().BatchNumber(data.ctx).Return(uint64(102), nil)
|
| 64 |
+
|
| 65 |
+
expectationsForSyncTrustedStateIteration(t, 100, notClosedBatch, data)
|
| 66 |
+
|
| 67 |
+
err := data.sut.SyncTrustedState(data.ctx, 100, 104)
|
| 68 |
+
require.NoError(t, err)
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
// This must process 100 (that is closed)
|
| 72 |
+
// and stop processing at 101 because is not yet close this batch
|
| 73 |
+
func TestSyncTrustedBatchesToFromStopAfterFirstWIPBatchCase2(t *testing.T) {
|
| 74 |
+
data := newTestDataTrustedBatchRetrieve(t)
|
| 75 |
+
data.mockZkEVMClient.EXPECT().BatchNumber(data.ctx).Return(uint64(102), nil)
|
| 76 |
+
|
| 77 |
+
expectationsForSyncTrustedStateIteration(t, 100, closedBatch, data)
|
| 78 |
+
expectationsForSyncTrustedStateIteration(t, 101, notClosedBatch, data)
|
| 79 |
+
|
| 80 |
+
err := data.sut.SyncTrustedState(data.ctx, 100, 104)
|
| 81 |
+
require.NoError(t, err)
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
// This test must do from 100 to 102. Is for check manually that the logs
|
| 85 |
+
// That is not tested but must not emit the log:
|
| 86 |
+
// - Batch 101 is not closed. so we break synchronization from Trusted Node because can only have 1 WIP batch on state
|
| 87 |
+
func TestSyncTrustedBatchesToFromStopAfterFirstWIPBatchCase3(t *testing.T) {
|
| 88 |
+
data := newTestDataTrustedBatchRetrieve(t)
|
| 89 |
+
data.mockZkEVMClient.EXPECT().BatchNumber(data.ctx).Return(uint64(102), nil)
|
| 90 |
+
expectationsForSyncTrustedStateIteration(t, 100, closedBatch, data)
|
| 91 |
+
expectationsForSyncTrustedStateIteration(t, 101, closedBatch, data)
|
| 92 |
+
expectationsForSyncTrustedStateIteration(t, 102, notClosedBatch, data)
|
| 93 |
+
|
| 94 |
+
err := data.sut.SyncTrustedState(data.ctx, 100, 102)
|
| 95 |
+
require.NoError(t, err)
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
func expectationsForSyncTrustedStateIteration(t *testing.T, batchNumber uint64, closed bool, data *testDataTrustedBatchRetrieve) {
|
| 99 |
+
batch100 := &types.Batch{
|
| 100 |
+
Number: types.ArgUint64(batchNumber),
|
| 101 |
+
Closed: closed,
|
| 102 |
+
}
|
| 103 |
+
data.mockZkEVMClient.EXPECT().BatchByNumber(data.ctx, big.NewInt(0).SetUint64(batchNumber)).Return(batch100, nil)
|
| 104 |
+
data.mockState.EXPECT().BeginStateTransaction(data.ctx).Return(data.mockDbTx, nil)
|
| 105 |
+
// Get Previous Batch 99 from State
|
| 106 |
+
stateBatch99 := &state.Batch{
|
| 107 |
+
BatchNumber: batchNumber - 1,
|
| 108 |
+
}
|
| 109 |
+
data.mockState.EXPECT().GetBatchByNumber(data.ctx, uint64(batchNumber-1), data.mockDbTx).Return(stateBatch99, nil)
|
| 110 |
+
stateBatch100 := &state.Batch{
|
| 111 |
+
BatchNumber: batchNumber,
|
| 112 |
+
}
|
| 113 |
+
data.mockState.EXPECT().GetBatchByNumber(data.ctx, uint64(batchNumber), data.mockDbTx).Return(stateBatch100, nil)
|
| 114 |
+
data.mockBatchProcessor.EXPECT().ProcessTrustedBatch(data.ctx, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, nil)
|
| 115 |
+
data.mockSync.EXPECT().CheckFlushID(mock.Anything).Return(nil)
|
| 116 |
+
data.mockDbTx.EXPECT().Commit(data.ctx).Return(nil)
|
| 117 |
+
}
|
|
@@ -109,6 +109,16 @@
|
|
| 109 |
return lastTrustedStateBatchNumber < latestSyncedBatch
|
| 110 |
}
|
| 111 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 112 |
func (s *TrustedBatchesRetrieve) syncTrustedBatchesToFrom(ctx context.Context, latestSyncedBatch uint64, lastTrustedStateBatchNumber uint64) error {
|
| 113 |
batchNumberToSync := max(latestSyncedBatch, s.firstBatchNumberToSync)
|
| 114 |
for batchNumberToSync <= lastTrustedStateBatchNumber {
|
|
@@ -120,6 +130,11 @@
|
|
| 120 |
log.Warnf("%s failed to get batch %d from trusted state. Error: %v", debugPrefix, batchNumberToSync, err)
|
| 121 |
return err
|
| 122 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 123 |
|
| 124 |
dbTx, err := s.state.BeginStateTransaction(ctx)
|
| 125 |
if err != nil {
|
|
@@ -161,6 +176,10 @@
|
|
| 161 |
s.TrustedStateMngr.Clear()
|
| 162 |
}
|
| 163 |
batchNumberToSync++
|
|
|
|
|
|
|
|
|
|
|
|
|
| 164 |
}
|
| 165 |
|
| 166 |
log.Infof("syncTrustedState: Trusted state fully synchronized from %d to %d", latestSyncedBatch, lastTrustedStateBatchNumber)
|
|
|
|
| 109 |
return lastTrustedStateBatchNumber < latestSyncedBatch
|
| 110 |
}
|
| 111 |
|
| 112 |
+
func sanityCheckBatchReturnedByTrusted(batch *types.Batch, expectedBatchNumber uint64) error {
|
| 113 |
+
if batch == nil {
|
| 114 |
+
return fmt.Errorf("batch %d is nil", expectedBatchNumber)
|
| 115 |
+
}
|
| 116 |
+
if uint64(batch.Number) != expectedBatchNumber {
|
| 117 |
+
return fmt.Errorf("batch %d is not the expected batch %d", batch.Number, expectedBatchNumber)
|
| 118 |
+
}
|
| 119 |
+
return nil
|
| 120 |
+
}
|
| 121 |
+
|
| 122 |
func (s *TrustedBatchesRetrieve) syncTrustedBatchesToFrom(ctx context.Context, latestSyncedBatch uint64, lastTrustedStateBatchNumber uint64) error {
|
| 123 |
batchNumberToSync := max(latestSyncedBatch, s.firstBatchNumberToSync)
|
| 124 |
for batchNumberToSync <= lastTrustedStateBatchNumber {
|
|
|
|
| 130 |
log.Warnf("%s failed to get batch %d from trusted state. Error: %v", debugPrefix, batchNumberToSync, err)
|
| 131 |
return err
|
| 132 |
}
|
| 133 |
+
err = sanityCheckBatchReturnedByTrusted(batchToSync, batchNumberToSync)
|
| 134 |
+
if err != nil {
|
| 135 |
+
log.Warnf("%s sanity check over Batch returned by Trusted-RPC failed: %v", debugPrefix, err)
|
| 136 |
+
return err
|
| 137 |
+
}
|
| 138 |
|
| 139 |
dbTx, err := s.state.BeginStateTransaction(ctx)
|
| 140 |
if err != nil {
|
|
|
|
| 176 |
s.TrustedStateMngr.Clear()
|
| 177 |
}
|
| 178 |
batchNumberToSync++
|
| 179 |
+
if !batchToSync.Closed && batchNumberToSync <= lastTrustedStateBatchNumber {
|
| 180 |
+
log.Infof("%s Batch %d is not closed. so we break synchronization from Trusted Node because can only have 1 WIP batch on state", debugPrefix, batchToSync.Number)
|
| 181 |
+
return nil
|
| 182 |
+
}
|
| 183 |
}
|
| 184 |
|
| 185 |
log.Infof("syncTrustedState: Trusted state fully synchronized from %d to %d", latestSyncedBatch, lastTrustedStateBatchNumber)
|
|
@@ -136,13 +137,13 @@
|
|
| 136 |
return nil, err
|
| 137 |
}
|
| 138 |
|
| 139 |
-
|
| 140 |
if err != nil {
|
| 141 |
log.Errorf("%s error getting GetL1InfoTreeDataFromBatchL2Data: %v. Error:%w", data.DebugPrefix, l1InfoRoot, err)
|
| 142 |
return nil, err
|
| 143 |
}
|
| 144 |
debugStr := data.DebugPrefix
|
| 145 |
-
processBatchResp, err := b.processAndStoreTxs(ctx, b.getProcessRequest(data,
|
| 146 |
if err != nil {
|
| 147 |
log.Error("%s error procesingAndStoringTxs. Error: ", debugStr, err)
|
| 148 |
return nil, err
|
|
@@ -197,7 +198,7 @@
|
|
| 197 |
return nil, err
|
| 198 |
}
|
| 199 |
|
| 200 |
-
|
| 201 |
if err != nil {
|
| 202 |
log.Errorf("%s error getting GetL1InfoTreeDataFromBatchL2Data: %v. Error:%w", data.DebugPrefix, l1InfoRoot, err)
|
| 203 |
// TODO: Need to refine, depending of the response of GetL1InfoTreeDataFromBatchL2Data
|
|
@@ -205,7 +206,7 @@
|
|
| 205 |
return nil, syncinterfaces.ErrMissingSyncFromL1
|
| 206 |
}
|
| 207 |
debugStr := fmt.Sprintf("%s: Batch %d:", data.Mode, uint64(data.TrustedBatch.Number))
|
| 208 |
-
processReq := b.getProcessRequest(data,
|
| 209 |
processReq.Transactions = PartialBatchL2Data
|
| 210 |
processBatchResp, err := b.processAndStoreTxs(ctx, processReq, dbTx, debugStr)
|
| 211 |
if err != nil {
|
|
@@ -429,6 +430,7 @@
|
|
| 429 |
Transactions: data.TrustedBatch.BatchL2Data,
|
| 430 |
ForkID: b.state.GetForkIDByBatchNumber(uint64(data.TrustedBatch.Number)),
|
| 431 |
SkipVerifyL1InfoRoot_V2: true,
|
|
|
|
| 432 |
}
|
| 433 |
return request
|
| 434 |
}
|
|
|
|
| 137 |
return nil, err
|
| 138 |
}
|
| 139 |
|
| 140 |
+
leaves, l1InfoRoot, _, err := b.state.GetL1InfoTreeDataFromBatchL2Data(ctx, data.TrustedBatch.BatchL2Data, dbTx)
|
| 141 |
if err != nil {
|
| 142 |
log.Errorf("%s error getting GetL1InfoTreeDataFromBatchL2Data: %v. Error:%w", data.DebugPrefix, l1InfoRoot, err)
|
| 143 |
return nil, err
|
| 144 |
}
|
| 145 |
debugStr := data.DebugPrefix
|
| 146 |
+
processBatchResp, err := b.processAndStoreTxs(ctx, b.getProcessRequest(data, leaves, l1InfoRoot), dbTx, debugStr)
|
| 147 |
if err != nil {
|
| 148 |
log.Error("%s error procesingAndStoringTxs. Error: ", debugStr, err)
|
| 149 |
return nil, err
|
|
|
|
| 198 |
return nil, err
|
| 199 |
}
|
| 200 |
|
| 201 |
+
leaves, l1InfoRoot, _, err := b.state.GetL1InfoTreeDataFromBatchL2Data(ctx, PartialBatchL2Data, dbTx)
|
| 202 |
if err != nil {
|
| 203 |
log.Errorf("%s error getting GetL1InfoTreeDataFromBatchL2Data: %v. Error:%w", data.DebugPrefix, l1InfoRoot, err)
|
| 204 |
// TODO: Need to refine, depending of the response of GetL1InfoTreeDataFromBatchL2Data
|
|
|
|
| 206 |
return nil, syncinterfaces.ErrMissingSyncFromL1
|
| 207 |
}
|
| 208 |
debugStr := fmt.Sprintf("%s: Batch %d:", data.Mode, uint64(data.TrustedBatch.Number))
|
| 209 |
+
processReq := b.getProcessRequest(data, leaves, l1InfoRoot)
|
| 210 |
processReq.Transactions = PartialBatchL2Data
|
| 211 |
processBatchResp, err := b.processAndStoreTxs(ctx, processReq, dbTx, debugStr)
|
| 212 |
if err != nil {
|
|
|
|
| 430 |
Transactions: data.TrustedBatch.BatchL2Data,
|
| 431 |
ForkID: b.state.GetForkIDByBatchNumber(uint64(data.TrustedBatch.Number)),
|
| 432 |
SkipVerifyL1InfoRoot_V2: true,
|
| 433 |
+
ExecutionMode: executor.ExecutionMode1,
|
| 434 |
}
|
| 435 |
return request
|
| 436 |
}
|
|
@@ -196,6 +196,7 @@
|
|
| 196 |
OldAccInputHash: batches[1].AccInputHash,
|
| 197 |
Coinbase: common.HexToAddress(trustedBatch.Coinbase.String()),
|
| 198 |
Timestamp_V1: time.Unix(int64(trustedBatch.Timestamp), 0),
|
|
|
|
| 199 |
}
|
| 200 |
// check if batch needs to be synchronized
|
| 201 |
if batches[0] != nil {
|
|
|
|
| 196 |
OldAccInputHash: batches[1].AccInputHash,
|
| 197 |
Coinbase: common.HexToAddress(trustedBatch.Coinbase.String()),
|
| 198 |
Timestamp_V1: time.Unix(int64(trustedBatch.Timestamp), 0),
|
| 199 |
+
ExecutionMode: executor.ExecutionMode1,
|
| 200 |
}
|
| 201 |
// check if batch needs to be synchronized
|
| 202 |
if batches[0] != nil {
|
|
@@ -16,12 +16,14 @@
|
|
| 16 |
"github.com/0xPolygonHermez/zkevm-node/synchronizer/actions/processor_manager"
|
| 17 |
syncCommon "github.com/0xPolygonHermez/zkevm-node/synchronizer/common"
|
| 18 |
"github.com/0xPolygonHermez/zkevm-node/synchronizer/common/syncinterfaces"
|
|
|
|
| 19 |
"github.com/0xPolygonHermez/zkevm-node/synchronizer/l1_parallel_sync"
|
| 20 |
"github.com/0xPolygonHermez/zkevm-node/synchronizer/l1event_orders"
|
| 21 |
"github.com/0xPolygonHermez/zkevm-node/synchronizer/l2_sync/l2_shared"
|
| 22 |
"github.com/0xPolygonHermez/zkevm-node/synchronizer/l2_sync/l2_sync_etrog"
|
| 23 |
"github.com/0xPolygonHermez/zkevm-node/synchronizer/metrics"
|
| 24 |
"github.com/ethereum/go-ethereum/common"
|
|
|
|
| 25 |
"github.com/jackc/pgx/v4"
|
| 26 |
)
|
| 27 |
|
|
@@ -52,17 +54,19 @@
|
|
| 52 |
etherMan syncinterfaces.EthermanFullInterface
|
| 53 |
latestFlushID uint64
|
| 54 |
// If true the lastFlushID is stored in DB and we don't need to check again
|
| 55 |
-
latestFlushIDIsFulfilled
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
|
|
|
|
|
|
| 66 |
// Id of the 'process' of the executor. Each time that it starts this value changes
|
| 67 |
// This value is obtained from the call state.GetStoredFlushID
|
| 68 |
// It starts as an empty string and it is filled in the first call
|
|
@@ -74,6 +78,7 @@
|
|
| 74 |
l1EventProcessors *processor_manager.L1EventProcessors
|
| 75 |
syncTrustedStateExecutor syncinterfaces.SyncTrustedStateExecutor
|
| 76 |
halter syncinterfaces.CriticalErrorHandler
|
|
|
|
| 77 |
}
|
| 78 |
|
| 79 |
// NewSynchronizer creates and initializes an instance of Synchronizer
|
|
@@ -85,30 +90,65 @@
|
|
| 85 |
pool syncinterfaces.PoolInterface,
|
| 86 |
ethTxManager syncinterfaces.EthTxManager,
|
| 87 |
zkEVMClient syncinterfaces.ZKEVMClientInterface,
|
|
|
|
| 88 |
eventLog syncinterfaces.EventLogInterface,
|
| 89 |
genesis state.Genesis,
|
| 90 |
cfg Config,
|
| 91 |
runInDevelopmentMode bool) (Synchronizer, error) {
|
| 92 |
ctx, cancel := context.WithCancel(context.Background())
|
| 93 |
metrics.Register()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 94 |
res := &ClientSynchronizer{
|
| 95 |
-
isTrustedSequencer:
|
| 96 |
-
state:
|
| 97 |
-
etherMan:
|
| 98 |
-
etherManForL1:
|
| 99 |
-
pool:
|
| 100 |
-
ctx:
|
| 101 |
-
cancelCtx:
|
| 102 |
-
ethTxManager:
|
| 103 |
-
zkEVMClient:
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 112 |
}
|
| 113 |
|
| 114 |
if !isTrustedSequencer {
|
|
@@ -143,7 +183,11 @@
|
|
| 143 |
log.Errorf("error getting last L2Block number from state. Error: %v", err)
|
| 144 |
return nil, err
|
| 145 |
}
|
| 146 |
-
l1checkerL2Blocks = actions.NewCheckL2BlockHash(res.state, res.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 147 |
} else {
|
| 148 |
log.Infof("Trusted Node can't check L2Block hash, ignoring parameter")
|
| 149 |
}
|
|
@@ -163,6 +207,19 @@
|
|
| 163 |
return res, nil
|
| 164 |
}
|
| 165 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 166 |
var waitDuration = time.Duration(0)
|
| 167 |
|
| 168 |
func newL1SyncParallel(ctx context.Context, cfg Config, etherManForL1 []syncinterfaces.EthermanFullInterface, sync *ClientSynchronizer, runExternalControl bool) *l1_parallel_sync.L1SyncOrchestration {
|
|
@@ -225,6 +282,10 @@
|
|
| 225 |
// If there is no lastEthereumBlock means that sync from the beginning is necessary. If not, it continues from the retrieved ethereum block
|
| 226 |
// Get the latest synced block. If there is no block on db, use genesis block
|
| 227 |
log.Info("Sync started")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 228 |
dbTx, err := s.state.BeginStateTransaction(s.ctx)
|
| 229 |
if err != nil {
|
| 230 |
log.Errorf("error creating db transaction to get latest block. Error: %v", err)
|
|
@@ -234,7 +295,7 @@
|
|
| 234 |
if err != nil {
|
| 235 |
if errors.Is(err, state.ErrStateNotSynchronized) {
|
| 236 |
log.Info("State is empty, verifying genesis block")
|
| 237 |
-
valid, err := s.etherMan.VerifyGenBlockNumber(s.ctx, s.genesis.
|
| 238 |
if err != nil {
|
| 239 |
log.Error("error checking genesis block number. Error: ", err)
|
| 240 |
return rollback(s.ctx, dbTx, err)
|
|
@@ -242,12 +303,42 @@
|
|
| 242 |
log.Error("genesis Block number configured is not valid. It is required the block number where the PolygonZkEVM smc was deployed")
|
| 243 |
return rollback(s.ctx, dbTx, fmt.Errorf("genesis Block number configured is not valid. It is required the block number where the PolygonZkEVM smc was deployed"))
|
| 244 |
}
|
| 245 |
-
|
| 246 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 247 |
if err != nil {
|
| 248 |
-
log.Errorf("error getting l1 block header for block %d. Error: %v", s.genesis.
|
| 249 |
return rollback(s.ctx, dbTx, err)
|
| 250 |
}
|
|
|
|
| 251 |
lastEthBlockSynced = &state.Block{
|
| 252 |
BlockNumber: header.Number.Uint64(),
|
| 253 |
BlockHash: header.Hash(),
|
|
@@ -346,6 +437,7 @@
|
|
| 346 |
continue
|
| 347 |
}
|
| 348 |
log.Infof("latestSequencedBatchNumber: %d, latestSyncedBatch: %d, lastVerifiedBatchNumber: %d", latestSequencedBatchNumber, latestSyncedBatch, lastVerifiedBatchNumber)
|
|
|
|
| 349 |
// Sync trusted state
|
| 350 |
// latestSyncedBatch -> Last batch on DB
|
| 351 |
// latestSequencedBatchNumber -> last batch on SMC
|
|
@@ -353,6 +445,13 @@
|
|
| 353 |
startTrusted := time.Now()
|
| 354 |
if s.syncTrustedStateExecutor != nil && !s.isTrustedSequencer {
|
| 355 |
log.Info("Syncing trusted state (permissionless)")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 356 |
err = s.syncTrustedState(latestSyncedBatch)
|
| 357 |
metrics.FullTrustedSyncTime(time.Since(startTrusted))
|
| 358 |
if err != nil {
|
|
@@ -361,10 +460,14 @@
|
|
| 361 |
if errors.Is(err, syncinterfaces.ErrFatalDesyncFromL1) {
|
| 362 |
l1BlockNumber := err.(*l2_shared.DeSyncPermissionlessAndTrustedNodeError).L1BlockNumber
|
| 363 |
log.Error("Trusted and permissionless desync! reseting to last common point: L1Block (%d-1)", l1BlockNumber)
|
| 364 |
-
|
| 365 |
-
|
| 366 |
-
|
| 367 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 368 |
}
|
| 369 |
} else if errors.Is(err, syncinterfaces.ErrMissingSyncFromL1) {
|
| 370 |
log.Info("Syncing from trusted node need data from L1")
|
|
@@ -381,6 +484,11 @@
|
|
| 381 |
waitDuration = s.cfg.SyncInterval.Duration
|
| 382 |
}
|
| 383 |
//Sync L1Blocks
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 384 |
startL1 := time.Now()
|
| 385 |
if s.l1SyncOrchestration != nil && (latestSyncedBatch < latestSequencedBatchNumber || !s.cfg.L1ParallelSynchronization.FallbackToSequentialModeOnSynchronized) {
|
| 386 |
log.Infof("Syncing L1 blocks in parallel lastEthBlockSynced=%d", lastEthBlockSynced.BlockNumber)
|
|
@@ -395,6 +503,19 @@
|
|
| 395 |
lastEthBlockSynced, err = s.syncBlocksSequential(lastEthBlockSynced)
|
| 396 |
}
|
| 397 |
metrics.FullL1SyncTime(time.Since(startL1))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 398 |
if err != nil {
|
| 399 |
log.Warn("error syncing blocks: ", err)
|
| 400 |
s.CleanTrustedState()
|
|
@@ -465,57 +586,35 @@
|
|
| 465 |
// This function syncs the node from a specific block to the latest
|
| 466 |
// lastEthBlockSynced -> last block synced in the db
|
| 467 |
func (s *ClientSynchronizer) syncBlocksParallel(lastEthBlockSynced *state.Block) (*state.Block, error) {
|
| 468 |
-
// This function will read events fromBlockNum to latestEthBlock. Check reorg to be sure that everything is ok.
|
| 469 |
-
block, err := s.checkReorg(lastEthBlockSynced)
|
| 470 |
-
if err != nil {
|
| 471 |
-
log.Errorf("error checking reorgs. Retrying... Err: %v", err)
|
| 472 |
-
return lastEthBlockSynced, fmt.Errorf("error checking reorgs")
|
| 473 |
-
}
|
| 474 |
-
if block != nil {
|
| 475 |
-
log.Infof("reorg detected. Resetting the state from block %v to block %v", lastEthBlockSynced.BlockNumber, block.BlockNumber)
|
| 476 |
-
err = s.resetState(block.BlockNumber)
|
| 477 |
-
if err != nil {
|
| 478 |
-
log.Errorf("error resetting the state to a previous block. Retrying... Err: %v", err)
|
| 479 |
-
s.l1SyncOrchestration.Reset(lastEthBlockSynced.BlockNumber)
|
| 480 |
-
return lastEthBlockSynced, fmt.Errorf("error resetting the state to a previous block")
|
| 481 |
-
}
|
| 482 |
-
return block, nil
|
| 483 |
-
}
|
| 484 |
log.Infof("Starting L1 sync orchestrator in parallel block: %d", lastEthBlockSynced.BlockNumber)
|
| 485 |
return s.l1SyncOrchestration.Start(lastEthBlockSynced)
|
| 486 |
}
|
| 487 |
|
| 488 |
// This function syncs the node from a specific block to the latest
|
| 489 |
func (s *ClientSynchronizer) syncBlocksSequential(lastEthBlockSynced *state.Block) (*state.Block, error) {
|
| 490 |
-
// This function will read events fromBlockNum to latestEthBlock. Check reorg to be sure that everything is ok.
|
| 491 |
-
block, err := s.checkReorg(lastEthBlockSynced)
|
| 492 |
-
if err != nil {
|
| 493 |
-
log.Errorf("error checking reorgs. Retrying... Err: %v", err)
|
| 494 |
-
return lastEthBlockSynced, fmt.Errorf("error checking reorgs")
|
| 495 |
-
}
|
| 496 |
-
if block != nil {
|
| 497 |
-
err = s.resetState(block.BlockNumber)
|
| 498 |
-
if err != nil {
|
| 499 |
-
log.Errorf("error resetting the state to a previous block. Retrying... Err: %v", err)
|
| 500 |
-
return lastEthBlockSynced, fmt.Errorf("error resetting the state to a previous block")
|
| 501 |
-
}
|
| 502 |
-
return block, nil
|
| 503 |
-
}
|
| 504 |
-
|
| 505 |
// Call the blockchain to retrieve data
|
| 506 |
-
header, err := s.etherMan.HeaderByNumber(s.ctx,
|
| 507 |
if err != nil {
|
|
|
|
| 508 |
return lastEthBlockSynced, err
|
| 509 |
}
|
| 510 |
lastKnownBlock := header.Number
|
| 511 |
|
| 512 |
var fromBlock uint64
|
| 513 |
if lastEthBlockSynced.BlockNumber > 0 {
|
| 514 |
-
fromBlock = lastEthBlockSynced.BlockNumber
|
| 515 |
}
|
|
|
|
| 516 |
|
| 517 |
for {
|
| 518 |
-
toBlock
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 519 |
log.Infof("Syncing block %d of %d", fromBlock, lastKnownBlock.Uint64())
|
| 520 |
log.Infof("Getting rollup info from block %d to block %d", fromBlock, toBlock)
|
| 521 |
// This function returns the rollup information contained in the ethereum blocks and an extra param called order.
|
|
@@ -529,6 +628,53 @@
|
|
| 529 |
if err != nil {
|
| 530 |
return lastEthBlockSynced, err
|
| 531 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 532 |
start = time.Now()
|
| 533 |
err = s.ProcessBlockRange(blocks, order)
|
| 534 |
metrics.ProcessL1DataTime(time.Since(start))
|
|
@@ -543,47 +689,36 @@
|
|
| 543 |
ReceivedAt: blocks[len(blocks)-1].ReceivedAt,
|
| 544 |
}
|
| 545 |
for i := range blocks {
|
| 546 |
-
log.
|
| 547 |
}
|
| 548 |
}
|
| 549 |
-
fromBlock = toBlock + 1
|
| 550 |
|
| 551 |
if lastKnownBlock.Cmp(new(big.Int).SetUint64(toBlock)) < 1 {
|
| 552 |
waitDuration = s.cfg.SyncInterval.Duration
|
| 553 |
break
|
| 554 |
}
|
| 555 |
-
|
| 556 |
-
|
| 557 |
-
|
| 558 |
-
if err != nil {
|
| 559 |
-
return lastEthBlockSynced, err
|
| 560 |
-
}
|
| 561 |
-
b := etherman.Block{
|
| 562 |
-
BlockNumber: fb.NumberU64(),
|
| 563 |
-
BlockHash: fb.Hash(),
|
| 564 |
-
ParentHash: fb.ParentHash(),
|
| 565 |
-
ReceivedAt: time.Unix(int64(fb.Time()), 0),
|
| 566 |
-
}
|
| 567 |
-
err = s.ProcessBlockRange([]etherman.Block{b}, order)
|
| 568 |
-
if err != nil {
|
| 569 |
-
return lastEthBlockSynced, err
|
| 570 |
-
}
|
| 571 |
-
block := state.Block{
|
| 572 |
-
BlockNumber: fb.NumberU64(),
|
| 573 |
-
BlockHash: fb.Hash(),
|
| 574 |
-
ParentHash: fb.ParentHash(),
|
| 575 |
-
ReceivedAt: time.Unix(int64(fb.Time()), 0),
|
| 576 |
-
}
|
| 577 |
-
lastEthBlockSynced = &block
|
| 578 |
-
log.Debug("Storing empty block. BlockNumber: ", b.BlockNumber, ". BlockHash: ", b.BlockHash)
|
| 579 |
-
}
|
| 580 |
}
|
| 581 |
|
| 582 |
return lastEthBlockSynced, nil
|
| 583 |
}
|
| 584 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 585 |
// ProcessBlockRange process the L1 events and stores the information in the db
|
| 586 |
func (s *ClientSynchronizer) ProcessBlockRange(blocks []etherman.Block, order map[common.Hash][]etherman.Order) error {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 587 |
// New info has to be included into the db using the state
|
| 588 |
for i := range blocks {
|
| 589 |
// Begin db transaction
|
|
@@ -598,9 +733,13 @@
|
|
| 598 |
ParentHash: blocks[i].ParentHash,
|
| 599 |
ReceivedAt: blocks[i].ReceivedAt,
|
| 600 |
}
|
|
|
|
|
|
|
|
|
|
| 601 |
// Add block information
|
| 602 |
err = s.state.AddBlock(s.ctx, &b, dbTx)
|
| 603 |
if err != nil {
|
|
|
|
| 604 |
log.Errorf("error storing block. BlockNumber: %d, error: %v", blocks[i].BlockNumber, err)
|
| 605 |
rollbackErr := dbTx.Rollback(s.ctx)
|
| 606 |
if rollbackErr != nil {
|
|
@@ -618,7 +757,7 @@
|
|
| 618 |
log.Debug("EventOrder: ", element.Name, ". Batch Sequence: ", batchSequence, "forkId: ", forkId)
|
| 619 |
} else {
|
| 620 |
forkId = s.state.GetForkIDByBlockNumber(blocks[i].BlockNumber)
|
| 621 |
-
log.Debug("EventOrder: ", element.Name, ". BlockNumber: ", blocks[i].BlockNumber, "forkId: ", forkId)
|
| 622 |
}
|
| 623 |
forkIdTyped := actions.ForkIdType(forkId)
|
| 624 |
// Process event received from l1
|
|
@@ -637,6 +776,7 @@
|
|
| 637 |
log.Debug("Checking FlushID to commit L1 data to db")
|
| 638 |
err = s.checkFlushID(dbTx)
|
| 639 |
if err != nil {
|
|
|
|
| 640 |
log.Errorf("error checking flushID. Error: %v", err)
|
| 641 |
rollbackErr := dbTx.Rollback(s.ctx)
|
| 642 |
if rollbackErr != nil {
|
|
@@ -647,6 +787,7 @@
|
|
| 647 |
}
|
| 648 |
err = dbTx.Commit(s.ctx)
|
| 649 |
if err != nil {
|
|
|
|
| 650 |
log.Errorf("error committing state to store block. BlockNumber: %d, err: %v", blocks[i].BlockNumber, err)
|
| 651 |
rollbackErr := dbTx.Rollback(s.ctx)
|
| 652 |
if rollbackErr != nil {
|
|
@@ -705,12 +846,118 @@
|
|
| 705 |
log.Error("error committing the resetted state. Error: ", err)
|
| 706 |
return err
|
| 707 |
}
|
|
|
|
|
|
|
|
|
|
| 708 |
if s.l1SyncOrchestration != nil {
|
| 709 |
-
s.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 710 |
}
|
| 711 |
return nil
|
| 712 |
}
|
| 713 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 714 |
/*
|
| 715 |
This function will check if there is a reorg.
|
| 716 |
As input param needs the last ethereum block synced. Retrieve the block info from the blockchain
|
|
@@ -719,31 +966,47 @@
|
|
| 719 |
must be reverted. Then, check the previous ethereum block synced, get block info from the blockchain and check
|
| 720 |
hash and has parent. This operation has to be done until a match is found.
|
| 721 |
*/
|
| 722 |
-
|
|
|
|
| 723 |
// This function only needs to worry about reorgs if some of the reorganized blocks contained rollup info.
|
| 724 |
-
|
|
|
|
| 725 |
var depth uint64
|
|
|
|
| 726 |
for {
|
| 727 |
-
block
|
| 728 |
-
|
| 729 |
-
|
| 730 |
-
|
| 731 |
-
|
| 732 |
-
|
| 733 |
-
|
| 734 |
-
|
| 735 |
-
|
| 736 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 737 |
}
|
|
|
|
|
|
|
|
|
|
| 738 |
// Compare hashes
|
| 739 |
-
if (block.
|
| 740 |
-
log.Infof("checkReorg: Bad block %d hashOk %t parentHashOk %t",
|
| 741 |
-
log.Debug("[checkReorg function] => latestBlockNumber: ",
|
| 742 |
-
log.Debug("[checkReorg function] => latestBlockHash: ",
|
| 743 |
-
log.Debug("[checkReorg function] => latestBlockHashParent: ",
|
| 744 |
-
log.Debug("[checkReorg function] => BlockNumber: ",
|
| 745 |
-
log.Debug("[checkReorg function] => BlockHash: ", block.
|
| 746 |
-
log.Debug("[checkReorg function] => BlockHashParent: ", block.ParentHash
|
| 747 |
depth++
|
| 748 |
log.Debug("REORG: Looking for the latest correct ethereum block. Depth: ", depth)
|
| 749 |
// Reorg detected. Getting previous block
|
|
@@ -752,7 +1015,7 @@
|
|
| 752 |
log.Errorf("error creating db transaction to get prevoius blocks")
|
| 753 |
return nil, err
|
| 754 |
}
|
| 755 |
-
|
| 756 |
errC := dbTx.Commit(s.ctx)
|
| 757 |
if errC != nil {
|
| 758 |
log.Errorf("error committing dbTx, err: %v", errC)
|
|
@@ -765,19 +1028,26 @@
|
|
| 765 |
return nil, errC
|
| 766 |
}
|
| 767 |
if errors.Is(err, state.ErrNotFound) {
|
| 768 |
-
log.Warn("error checking reorg: previous block not found in db: ", err)
|
| 769 |
-
return &
|
| 770 |
} else if err != nil {
|
|
|
|
| 771 |
return nil, err
|
| 772 |
}
|
|
|
|
| 773 |
} else {
|
|
|
|
| 774 |
break
|
| 775 |
}
|
|
|
|
|
|
|
| 776 |
}
|
| 777 |
-
if
|
| 778 |
-
|
| 779 |
-
|
|
|
|
| 780 |
}
|
|
|
|
| 781 |
return nil, nil
|
| 782 |
}
|
| 783 |
|
|
|
|
| 16 |
"github.com/0xPolygonHermez/zkevm-node/synchronizer/actions/processor_manager"
|
| 17 |
syncCommon "github.com/0xPolygonHermez/zkevm-node/synchronizer/common"
|
| 18 |
"github.com/0xPolygonHermez/zkevm-node/synchronizer/common/syncinterfaces"
|
| 19 |
+
"github.com/0xPolygonHermez/zkevm-node/synchronizer/l1_check_block"
|
| 20 |
"github.com/0xPolygonHermez/zkevm-node/synchronizer/l1_parallel_sync"
|
| 21 |
"github.com/0xPolygonHermez/zkevm-node/synchronizer/l1event_orders"
|
| 22 |
"github.com/0xPolygonHermez/zkevm-node/synchronizer/l2_sync/l2_shared"
|
| 23 |
"github.com/0xPolygonHermez/zkevm-node/synchronizer/l2_sync/l2_sync_etrog"
|
| 24 |
"github.com/0xPolygonHermez/zkevm-node/synchronizer/metrics"
|
| 25 |
"github.com/ethereum/go-ethereum/common"
|
| 26 |
+
"github.com/ethereum/go-ethereum/rpc"
|
| 27 |
"github.com/jackc/pgx/v4"
|
| 28 |
)
|
| 29 |
|
|
|
|
| 54 |
etherMan syncinterfaces.EthermanFullInterface
|
| 55 |
latestFlushID uint64
|
| 56 |
// If true the lastFlushID is stored in DB and we don't need to check again
|
| 57 |
+
latestFlushIDIsFulfilled bool
|
| 58 |
+
syncBlockProtection rpc.BlockNumber
|
| 59 |
+
etherManForL1 []syncinterfaces.EthermanFullInterface
|
| 60 |
+
state syncinterfaces.StateFullInterface
|
| 61 |
+
pool syncinterfaces.PoolInterface
|
| 62 |
+
ethTxManager syncinterfaces.EthTxManager
|
| 63 |
+
zkEVMClient syncinterfaces.ZKEVMClientInterface
|
| 64 |
+
zkEVMClientEthereumCompatible syncinterfaces.ZKEVMClientEthereumCompatibleInterface
|
| 65 |
+
eventLog syncinterfaces.EventLogInterface
|
| 66 |
+
ctx context.Context
|
| 67 |
+
cancelCtx context.CancelFunc
|
| 68 |
+
genesis state.Genesis
|
| 69 |
+
cfg Config
|
| 70 |
// Id of the 'process' of the executor. Each time that it starts this value changes
|
| 71 |
// This value is obtained from the call state.GetStoredFlushID
|
| 72 |
// It starts as an empty string and it is filled in the first call
|
|
|
|
| 78 |
l1EventProcessors *processor_manager.L1EventProcessors
|
| 79 |
syncTrustedStateExecutor syncinterfaces.SyncTrustedStateExecutor
|
| 80 |
halter syncinterfaces.CriticalErrorHandler
|
| 81 |
+
asyncL1BlockChecker syncinterfaces.L1BlockCheckerIntegrator
|
| 82 |
}
|
| 83 |
|
| 84 |
// NewSynchronizer creates and initializes an instance of Synchronizer
|
|
|
|
| 90 |
pool syncinterfaces.PoolInterface,
|
| 91 |
ethTxManager syncinterfaces.EthTxManager,
|
| 92 |
zkEVMClient syncinterfaces.ZKEVMClientInterface,
|
| 93 |
+
zkEVMClientEthereumCompatible syncinterfaces.ZKEVMClientEthereumCompatibleInterface,
|
| 94 |
eventLog syncinterfaces.EventLogInterface,
|
| 95 |
genesis state.Genesis,
|
| 96 |
cfg Config,
|
| 97 |
runInDevelopmentMode bool) (Synchronizer, error) {
|
| 98 |
ctx, cancel := context.WithCancel(context.Background())
|
| 99 |
metrics.Register()
|
| 100 |
+
syncBlockProtection, err := decodeSyncBlockProtection(cfg.SyncBlockProtection)
|
| 101 |
+
if err != nil {
|
| 102 |
+
log.Errorf("error decoding syncBlockProtection. Error: %v", err)
|
| 103 |
+
cancel()
|
| 104 |
+
return nil, err
|
| 105 |
+
}
|
| 106 |
+
log.Info("syncBlockProtection: ", syncBlockProtection)
|
| 107 |
res := &ClientSynchronizer{
|
| 108 |
+
isTrustedSequencer: isTrustedSequencer,
|
| 109 |
+
state: st,
|
| 110 |
+
etherMan: ethMan,
|
| 111 |
+
etherManForL1: etherManForL1,
|
| 112 |
+
pool: pool,
|
| 113 |
+
ctx: ctx,
|
| 114 |
+
cancelCtx: cancel,
|
| 115 |
+
ethTxManager: ethTxManager,
|
| 116 |
+
zkEVMClient: zkEVMClient,
|
| 117 |
+
zkEVMClientEthereumCompatible: zkEVMClientEthereumCompatible,
|
| 118 |
+
eventLog: eventLog,
|
| 119 |
+
genesis: genesis,
|
| 120 |
+
cfg: cfg,
|
| 121 |
+
proverID: "",
|
| 122 |
+
previousExecutorFlushID: 0,
|
| 123 |
+
l1SyncOrchestration: nil,
|
| 124 |
+
l1EventProcessors: nil,
|
| 125 |
+
syncBlockProtection: syncBlockProtection,
|
| 126 |
+
halter: syncCommon.NewCriticalErrorHalt(eventLog, 5*time.Second), //nolint:gomnd
|
| 127 |
+
}
|
| 128 |
+
if cfg.L1BlockCheck.Enable {
|
| 129 |
+
log.Infof("L1BlockChecker enabled: %s", cfg.L1BlockCheck.String())
|
| 130 |
+
l1BlockChecker := l1_check_block.NewCheckL1BlockHash(ethMan, res.state,
|
| 131 |
+
l1_check_block.NewSafeL1BlockNumberFetch(l1_check_block.StringToL1BlockPoint(cfg.L1BlockCheck.L1SafeBlockPoint), cfg.L1BlockCheck.L1SafeBlockOffset))
|
| 132 |
+
|
| 133 |
+
var preCheckAsync syncinterfaces.AsyncL1BlockChecker
|
| 134 |
+
if cfg.L1BlockCheck.PreCheckEnable {
|
| 135 |
+
log.Infof("L1BlockChecker enabled precheck from: %s/%d to: %s/%d",
|
| 136 |
+
cfg.L1BlockCheck.L1SafeBlockPoint, cfg.L1BlockCheck.L1SafeBlockOffset,
|
| 137 |
+
cfg.L1BlockCheck.L1PreSafeBlockPoint, cfg.L1BlockCheck.L1PreSafeBlockOffset)
|
| 138 |
+
l1BlockPreChecker := l1_check_block.NewPreCheckL1BlockHash(ethMan, res.state,
|
| 139 |
+
l1_check_block.NewSafeL1BlockNumberFetch(l1_check_block.StringToL1BlockPoint(cfg.L1BlockCheck.L1SafeBlockPoint), cfg.L1BlockCheck.L1SafeBlockOffset),
|
| 140 |
+
l1_check_block.NewSafeL1BlockNumberFetch(l1_check_block.StringToL1BlockPoint(cfg.L1BlockCheck.L1PreSafeBlockPoint), cfg.L1BlockCheck.L1PreSafeBlockOffset),
|
| 141 |
+
)
|
| 142 |
+
preCheckAsync = l1_check_block.NewAsyncCheck(l1BlockPreChecker)
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
res.asyncL1BlockChecker = l1_check_block.NewL1BlockCheckerIntegration(
|
| 146 |
+
l1_check_block.NewAsyncCheck(l1BlockChecker),
|
| 147 |
+
preCheckAsync,
|
| 148 |
+
res.state,
|
| 149 |
+
res,
|
| 150 |
+
cfg.L1BlockCheck.ForceCheckBeforeStart,
|
| 151 |
+
time.Second)
|
| 152 |
}
|
| 153 |
|
| 154 |
if !isTrustedSequencer {
|
|
|
|
| 183 |
log.Errorf("error getting last L2Block number from state. Error: %v", err)
|
| 184 |
return nil, err
|
| 185 |
}
|
| 186 |
+
l1checkerL2Blocks, err = actions.NewCheckL2BlockHash(res.state, res.zkEVMClientEthereumCompatible, initialL2Block, cfg.L1SyncCheckL2BlockNumberhModulus)
|
| 187 |
+
if err != nil {
|
| 188 |
+
log.Error("error creating new instance of checkL2BlockHash. Error: ", err)
|
| 189 |
+
return nil, err
|
| 190 |
+
}
|
| 191 |
} else {
|
| 192 |
log.Infof("Trusted Node can't check L2Block hash, ignoring parameter")
|
| 193 |
}
|
|
|
|
| 207 |
return res, nil
|
| 208 |
}
|
| 209 |
|
| 210 |
+
func decodeSyncBlockProtection(sBP string) (rpc.BlockNumber, error) {
|
| 211 |
+
switch sBP {
|
| 212 |
+
case "latest":
|
| 213 |
+
return rpc.LatestBlockNumber, nil
|
| 214 |
+
case "finalized":
|
| 215 |
+
return rpc.FinalizedBlockNumber, nil
|
| 216 |
+
case "safe":
|
| 217 |
+
return rpc.SafeBlockNumber, nil
|
| 218 |
+
default:
|
| 219 |
+
return 0, fmt.Errorf("error decoding SyncBlockProtection. Unknown value")
|
| 220 |
+
}
|
| 221 |
+
}
|
| 222 |
+
|
| 223 |
var waitDuration = time.Duration(0)
|
| 224 |
|
| 225 |
func newL1SyncParallel(ctx context.Context, cfg Config, etherManForL1 []syncinterfaces.EthermanFullInterface, sync *ClientSynchronizer, runExternalControl bool) *l1_parallel_sync.L1SyncOrchestration {
|
|
|
|
| 282 |
// If there is no lastEthereumBlock means that sync from the beginning is necessary. If not, it continues from the retrieved ethereum block
|
| 283 |
// Get the latest synced block. If there is no block on db, use genesis block
|
| 284 |
log.Info("Sync started")
|
| 285 |
+
if s.asyncL1BlockChecker != nil {
|
| 286 |
+
_ = s.asyncL1BlockChecker.OnStart(s.ctx)
|
| 287 |
+
}
|
| 288 |
+
|
| 289 |
dbTx, err := s.state.BeginStateTransaction(s.ctx)
|
| 290 |
if err != nil {
|
| 291 |
log.Errorf("error creating db transaction to get latest block. Error: %v", err)
|
|
|
|
| 295 |
if err != nil {
|
| 296 |
if errors.Is(err, state.ErrStateNotSynchronized) {
|
| 297 |
log.Info("State is empty, verifying genesis block")
|
| 298 |
+
valid, err := s.etherMan.VerifyGenBlockNumber(s.ctx, s.genesis.RollupBlockNumber)
|
| 299 |
if err != nil {
|
| 300 |
log.Error("error checking genesis block number. Error: ", err)
|
| 301 |
return rollback(s.ctx, dbTx, err)
|
|
|
|
| 303 |
log.Error("genesis Block number configured is not valid. It is required the block number where the PolygonZkEVM smc was deployed")
|
| 304 |
return rollback(s.ctx, dbTx, fmt.Errorf("genesis Block number configured is not valid. It is required the block number where the PolygonZkEVM smc was deployed"))
|
| 305 |
}
|
| 306 |
+
|
| 307 |
+
// Sync events from RollupManager that happen before rollup creation
|
| 308 |
+
log.Info("synchronizing events from RollupManager that happen before rollup creation")
|
| 309 |
+
for i := s.genesis.RollupManagerBlockNumber; true; i += s.cfg.SyncChunkSize {
|
| 310 |
+
toBlock := min(i+s.cfg.SyncChunkSize-1, s.genesis.RollupBlockNumber-1)
|
| 311 |
+
blocks, order, err := s.etherMan.GetRollupInfoByBlockRange(s.ctx, i, &toBlock)
|
| 312 |
+
if err != nil {
|
| 313 |
+
log.Error("error getting rollupInfoByBlockRange before rollup genesis: ", err)
|
| 314 |
+
rollbackErr := dbTx.Rollback(s.ctx)
|
| 315 |
+
if rollbackErr != nil {
|
| 316 |
+
log.Errorf("error rolling back state. RollbackErr: %v, err: %s", rollbackErr, err.Error())
|
| 317 |
+
return rollbackErr
|
| 318 |
+
}
|
| 319 |
+
return err
|
| 320 |
+
}
|
| 321 |
+
err = s.ProcessBlockRange(blocks, order)
|
| 322 |
+
if err != nil {
|
| 323 |
+
log.Error("error processing blocks before the genesis: ", err)
|
| 324 |
+
rollbackErr := dbTx.Rollback(s.ctx)
|
| 325 |
+
if rollbackErr != nil {
|
| 326 |
+
log.Errorf("error rolling back state. RollbackErr: %v, err: %s", rollbackErr, err.Error())
|
| 327 |
+
return rollbackErr
|
| 328 |
+
}
|
| 329 |
+
return err
|
| 330 |
+
}
|
| 331 |
+
if toBlock == s.genesis.RollupBlockNumber-1 {
|
| 332 |
+
break
|
| 333 |
+
}
|
| 334 |
+
}
|
| 335 |
+
|
| 336 |
+
header, err := s.etherMan.HeaderByNumber(s.ctx, big.NewInt(0).SetUint64(s.genesis.RollupBlockNumber))
|
| 337 |
if err != nil {
|
| 338 |
+
log.Errorf("error getting l1 block header for block %d. Error: %v", s.genesis.RollupBlockNumber, err)
|
| 339 |
return rollback(s.ctx, dbTx, err)
|
| 340 |
}
|
| 341 |
+
log.Info("synchronizing rollup creation block")
|
| 342 |
lastEthBlockSynced = &state.Block{
|
| 343 |
BlockNumber: header.Number.Uint64(),
|
| 344 |
BlockHash: header.Hash(),
|
|
|
|
| 437 |
continue
|
| 438 |
}
|
| 439 |
log.Infof("latestSequencedBatchNumber: %d, latestSyncedBatch: %d, lastVerifiedBatchNumber: %d", latestSequencedBatchNumber, latestSyncedBatch, lastVerifiedBatchNumber)
|
| 440 |
+
resetDone := false
|
| 441 |
// Sync trusted state
|
| 442 |
// latestSyncedBatch -> Last batch on DB
|
| 443 |
// latestSequencedBatchNumber -> last batch on SMC
|
|
|
|
| 445 |
startTrusted := time.Now()
|
| 446 |
if s.syncTrustedStateExecutor != nil && !s.isTrustedSequencer {
|
| 447 |
log.Info("Syncing trusted state (permissionless)")
|
| 448 |
+
//Sync Trusted State
|
| 449 |
+
log.Debug("Doing reorg check before L2 sync")
|
| 450 |
+
resetDone, lastEthBlockSynced, err = s.checkReorgAndExecuteReset(lastEthBlockSynced)
|
| 451 |
+
if resetDone || err != nil {
|
| 452 |
+
log.Infof("Reset done before L2 sync")
|
| 453 |
+
continue
|
| 454 |
+
}
|
| 455 |
err = s.syncTrustedState(latestSyncedBatch)
|
| 456 |
metrics.FullTrustedSyncTime(time.Since(startTrusted))
|
| 457 |
if err != nil {
|
|
|
|
| 460 |
if errors.Is(err, syncinterfaces.ErrFatalDesyncFromL1) {
|
| 461 |
l1BlockNumber := err.(*l2_shared.DeSyncPermissionlessAndTrustedNodeError).L1BlockNumber
|
| 462 |
log.Error("Trusted and permissionless desync! reseting to last common point: L1Block (%d-1)", l1BlockNumber)
|
| 463 |
+
for {
|
| 464 |
+
resetDone, lastEthBlockSynced, err = s.detectedReorgBadBlockExecuteReset(lastEthBlockSynced, syncCommon.GetReorgErrorBlockNumber(err))
|
| 465 |
+
if resetDone {
|
| 466 |
+
break
|
| 467 |
+
} else {
|
| 468 |
+
log.Error("reorg isn't done, retrying...")
|
| 469 |
+
time.Sleep(time.Second)
|
| 470 |
+
}
|
| 471 |
}
|
| 472 |
} else if errors.Is(err, syncinterfaces.ErrMissingSyncFromL1) {
|
| 473 |
log.Info("Syncing from trusted node need data from L1")
|
|
|
|
| 484 |
waitDuration = s.cfg.SyncInterval.Duration
|
| 485 |
}
|
| 486 |
//Sync L1Blocks
|
| 487 |
+
resetDone, lastEthBlockSynced, err = s.checkReorgAndExecuteReset(lastEthBlockSynced)
|
| 488 |
+
if resetDone || err != nil {
|
| 489 |
+
continue
|
| 490 |
+
}
|
| 491 |
+
|
| 492 |
startL1 := time.Now()
|
| 493 |
if s.l1SyncOrchestration != nil && (latestSyncedBatch < latestSequencedBatchNumber || !s.cfg.L1ParallelSynchronization.FallbackToSequentialModeOnSynchronized) {
|
| 494 |
log.Infof("Syncing L1 blocks in parallel lastEthBlockSynced=%d", lastEthBlockSynced.BlockNumber)
|
|
|
|
| 503 |
lastEthBlockSynced, err = s.syncBlocksSequential(lastEthBlockSynced)
|
| 504 |
}
|
| 505 |
metrics.FullL1SyncTime(time.Since(startL1))
|
| 506 |
+
if syncCommon.IsReorgError(err) {
|
| 507 |
+
log.Warnf("error syncing blocks: %s", err.Error())
|
| 508 |
+
for {
|
| 509 |
+
resetDone, lastEthBlockSynced, err = s.detectedReorgBadBlockExecuteReset(lastEthBlockSynced, syncCommon.GetReorgErrorBlockNumber(err))
|
| 510 |
+
if resetDone {
|
| 511 |
+
break
|
| 512 |
+
} else {
|
| 513 |
+
log.Error("reorg isn't done, retrying...")
|
| 514 |
+
time.Sleep(time.Second)
|
| 515 |
+
}
|
| 516 |
+
}
|
| 517 |
+
continue
|
| 518 |
+
}
|
| 519 |
if err != nil {
|
| 520 |
log.Warn("error syncing blocks: ", err)
|
| 521 |
s.CleanTrustedState()
|
|
|
|
| 586 |
// This function syncs the node from a specific block to the latest
|
| 587 |
// lastEthBlockSynced -> last block synced in the db
|
| 588 |
func (s *ClientSynchronizer) syncBlocksParallel(lastEthBlockSynced *state.Block) (*state.Block, error) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 589 |
log.Infof("Starting L1 sync orchestrator in parallel block: %d", lastEthBlockSynced.BlockNumber)
|
| 590 |
return s.l1SyncOrchestration.Start(lastEthBlockSynced)
|
| 591 |
}
|
| 592 |
|
| 593 |
// This function syncs the node from a specific block to the latest
|
| 594 |
func (s *ClientSynchronizer) syncBlocksSequential(lastEthBlockSynced *state.Block) (*state.Block, error) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 595 |
// Call the blockchain to retrieve data
|
| 596 |
+
header, err := s.etherMan.HeaderByNumber(s.ctx, big.NewInt(s.syncBlockProtection.Int64()))
|
| 597 |
if err != nil {
|
| 598 |
+
log.Error("error getting header of the latest block in L1. Error: ", err)
|
| 599 |
return lastEthBlockSynced, err
|
| 600 |
}
|
| 601 |
lastKnownBlock := header.Number
|
| 602 |
|
| 603 |
var fromBlock uint64
|
| 604 |
if lastEthBlockSynced.BlockNumber > 0 {
|
| 605 |
+
fromBlock = lastEthBlockSynced.BlockNumber
|
| 606 |
}
|
| 607 |
+
toBlock := fromBlock + s.cfg.SyncChunkSize
|
| 608 |
|
| 609 |
for {
|
| 610 |
+
if toBlock > lastKnownBlock.Uint64() {
|
| 611 |
+
log.Debug("Setting toBlock to the lastKnownBlock")
|
| 612 |
+
toBlock = lastKnownBlock.Uint64()
|
| 613 |
+
}
|
| 614 |
+
if fromBlock > toBlock {
|
| 615 |
+
log.Debug("FromBlock is higher than toBlock. Skipping...")
|
| 616 |
+
return lastEthBlockSynced, nil
|
| 617 |
+
}
|
| 618 |
log.Infof("Syncing block %d of %d", fromBlock, lastKnownBlock.Uint64())
|
| 619 |
log.Infof("Getting rollup info from block %d to block %d", fromBlock, toBlock)
|
| 620 |
// This function returns the rollup information contained in the ethereum blocks and an extra param called order.
|
|
|
|
| 628 |
if err != nil {
|
| 629 |
return lastEthBlockSynced, err
|
| 630 |
}
|
| 631 |
+
|
| 632 |
+
var initBlockReceived *etherman.Block
|
| 633 |
+
if len(blocks) != 0 {
|
| 634 |
+
initBlockReceived = &blocks[0]
|
| 635 |
+
// First position of the array must be deleted
|
| 636 |
+
blocks = removeBlockElement(blocks, 0)
|
| 637 |
+
} else {
|
| 638 |
+
// Reorg detected
|
| 639 |
+
log.Infof("Reorg detected in block %d while querying GetRollupInfoByBlockRange. Rolling back to at least the previous block", fromBlock)
|
| 640 |
+
prevBlock, err := s.state.GetPreviousBlock(s.ctx, 1, nil)
|
| 641 |
+
if errors.Is(err, state.ErrNotFound) {
|
| 642 |
+
log.Warn("error checking reorg: previous block not found in db: ", err)
|
| 643 |
+
prevBlock = &state.Block{}
|
| 644 |
+
} else if err != nil {
|
| 645 |
+
log.Error("error getting previousBlock from db. Error: ", err)
|
| 646 |
+
return lastEthBlockSynced, err
|
| 647 |
+
}
|
| 648 |
+
blockReorged, err := s.checkReorg(prevBlock, nil)
|
| 649 |
+
if err != nil {
|
| 650 |
+
log.Error("error checking reorgs in previous blocks. Error: ", err)
|
| 651 |
+
return lastEthBlockSynced, err
|
| 652 |
+
}
|
| 653 |
+
if blockReorged == nil {
|
| 654 |
+
blockReorged = prevBlock
|
| 655 |
+
}
|
| 656 |
+
err = s.resetState(blockReorged.BlockNumber)
|
| 657 |
+
if err != nil {
|
| 658 |
+
log.Errorf("error resetting the state to a previous block. Retrying... Err: %v", err)
|
| 659 |
+
return lastEthBlockSynced, fmt.Errorf("error resetting the state to a previous block")
|
| 660 |
+
}
|
| 661 |
+
return blockReorged, nil
|
| 662 |
+
}
|
| 663 |
+
// Check reorg again to be sure that the chain has not changed between the previous checkReorg and the call GetRollupInfoByBlockRange
|
| 664 |
+
block, err := s.checkReorg(lastEthBlockSynced, initBlockReceived)
|
| 665 |
+
if err != nil {
|
| 666 |
+
log.Errorf("error checking reorgs. Retrying... Err: %v", err)
|
| 667 |
+
return lastEthBlockSynced, fmt.Errorf("error checking reorgs")
|
| 668 |
+
}
|
| 669 |
+
if block != nil {
|
| 670 |
+
err = s.resetState(block.BlockNumber)
|
| 671 |
+
if err != nil {
|
| 672 |
+
log.Errorf("error resetting the state to a previous block. Retrying... Err: %v", err)
|
| 673 |
+
return lastEthBlockSynced, fmt.Errorf("error resetting the state to a previous block")
|
| 674 |
+
}
|
| 675 |
+
return block, nil
|
| 676 |
+
}
|
| 677 |
+
|
| 678 |
start = time.Now()
|
| 679 |
err = s.ProcessBlockRange(blocks, order)
|
| 680 |
metrics.ProcessL1DataTime(time.Since(start))
|
|
|
|
| 689 |
ReceivedAt: blocks[len(blocks)-1].ReceivedAt,
|
| 690 |
}
|
| 691 |
for i := range blocks {
|
| 692 |
+
log.Info("Position: ", i, ". New block. BlockNumber: ", blocks[i].BlockNumber, ". BlockHash: ", blocks[i].BlockHash)
|
| 693 |
}
|
| 694 |
}
|
|
|
|
| 695 |
|
| 696 |
if lastKnownBlock.Cmp(new(big.Int).SetUint64(toBlock)) < 1 {
|
| 697 |
waitDuration = s.cfg.SyncInterval.Duration
|
| 698 |
break
|
| 699 |
}
|
| 700 |
+
|
| 701 |
+
fromBlock = lastEthBlockSynced.BlockNumber
|
| 702 |
+
toBlock = toBlock + s.cfg.SyncChunkSize
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 703 |
}
|
| 704 |
|
| 705 |
return lastEthBlockSynced, nil
|
| 706 |
}
|
| 707 |
|
| 708 |
+
func removeBlockElement(slice []etherman.Block, s int) []etherman.Block {
|
| 709 |
+
ret := make([]etherman.Block, 0)
|
| 710 |
+
ret = append(ret, slice[:s]...)
|
| 711 |
+
return append(ret, slice[s+1:]...)
|
| 712 |
+
}
|
| 713 |
+
|
| 714 |
// ProcessBlockRange process the L1 events and stores the information in the db
|
| 715 |
func (s *ClientSynchronizer) ProcessBlockRange(blocks []etherman.Block, order map[common.Hash][]etherman.Order) error {
|
| 716 |
+
// Check the latest finalized block in L1
|
| 717 |
+
finalizedBlockNumber, err := s.etherMan.GetFinalizedBlockNumber(s.ctx)
|
| 718 |
+
if err != nil {
|
| 719 |
+
log.Errorf("error getting finalized block number in L1. Error: %v", err)
|
| 720 |
+
return err
|
| 721 |
+
}
|
| 722 |
// New info has to be included into the db using the state
|
| 723 |
for i := range blocks {
|
| 724 |
// Begin db transaction
|
|
|
|
| 733 |
ParentHash: blocks[i].ParentHash,
|
| 734 |
ReceivedAt: blocks[i].ReceivedAt,
|
| 735 |
}
|
| 736 |
+
if blocks[i].BlockNumber <= finalizedBlockNumber {
|
| 737 |
+
b.Checked = true
|
| 738 |
+
}
|
| 739 |
// Add block information
|
| 740 |
err = s.state.AddBlock(s.ctx, &b, dbTx)
|
| 741 |
if err != nil {
|
| 742 |
+
// If any goes wrong we ensure that the state is rollbacked
|
| 743 |
log.Errorf("error storing block. BlockNumber: %d, error: %v", blocks[i].BlockNumber, err)
|
| 744 |
rollbackErr := dbTx.Rollback(s.ctx)
|
| 745 |
if rollbackErr != nil {
|
|
|
|
| 757 |
log.Debug("EventOrder: ", element.Name, ". Batch Sequence: ", batchSequence, "forkId: ", forkId)
|
| 758 |
} else {
|
| 759 |
forkId = s.state.GetForkIDByBlockNumber(blocks[i].BlockNumber)
|
| 760 |
+
log.Debug("EventOrder: ", element.Name, ". BlockNumber: ", blocks[i].BlockNumber, ". forkId: ", forkId)
|
| 761 |
}
|
| 762 |
forkIdTyped := actions.ForkIdType(forkId)
|
| 763 |
// Process event received from l1
|
|
|
|
| 776 |
log.Debug("Checking FlushID to commit L1 data to db")
|
| 777 |
err = s.checkFlushID(dbTx)
|
| 778 |
if err != nil {
|
| 779 |
+
// If any goes wrong we ensure that the state is rollbacked
|
| 780 |
log.Errorf("error checking flushID. Error: %v", err)
|
| 781 |
rollbackErr := dbTx.Rollback(s.ctx)
|
| 782 |
if rollbackErr != nil {
|
|
|
|
| 787 |
}
|
| 788 |
err = dbTx.Commit(s.ctx)
|
| 789 |
if err != nil {
|
| 790 |
+
// If any goes wrong we ensure that the state is rollbacked
|
| 791 |
log.Errorf("error committing state to store block. BlockNumber: %d, err: %v", blocks[i].BlockNumber, err)
|
| 792 |
rollbackErr := dbTx.Rollback(s.ctx)
|
| 793 |
if rollbackErr != nil {
|
|
|
|
| 846 |
log.Error("error committing the resetted state. Error: ", err)
|
| 847 |
return err
|
| 848 |
}
|
| 849 |
+
if s.asyncL1BlockChecker != nil {
|
| 850 |
+
s.asyncL1BlockChecker.OnResetState(s.ctx)
|
| 851 |
+
}
|
| 852 |
if s.l1SyncOrchestration != nil {
|
| 853 |
+
lastBlock, err := s.state.GetLastBlock(s.ctx, nil)
|
| 854 |
+
if err != nil {
|
| 855 |
+
log.Errorf("error getting last block synced from db. Error: %v", err)
|
| 856 |
+
s.l1SyncOrchestration.Reset(blockNumber)
|
| 857 |
+
} else {
|
| 858 |
+
s.l1SyncOrchestration.Reset(lastBlock.BlockNumber)
|
| 859 |
+
}
|
| 860 |
}
|
| 861 |
return nil
|
| 862 |
}
|
| 863 |
|
| 864 |
+
// OnDetectedMismatchL1BlockReorg function will be called when a reorg is detected (asynchronous call)
|
| 865 |
+
func (s *ClientSynchronizer) OnDetectedMismatchL1BlockReorg() {
|
| 866 |
+
log.Infof("Detected Reorg in background at block (mismatch)")
|
| 867 |
+
if s.l1SyncOrchestration != nil && s.l1SyncOrchestration.IsProducerRunning() {
|
| 868 |
+
log.Errorf("Stop synchronizer: because L1 sync parallel aborting background process")
|
| 869 |
+
s.l1SyncOrchestration.Abort()
|
| 870 |
+
}
|
| 871 |
+
}
|
| 872 |
+
|
| 873 |
+
// ExecuteReorgFromMismatchBlock function will reset the state to the block before the bad block
|
| 874 |
+
func (s *ClientSynchronizer) ExecuteReorgFromMismatchBlock(blockNumber uint64, reason string) error {
|
| 875 |
+
log.Info("Detected reorg at block (mismatch): ", blockNumber, " reason: ", reason, " resetting the state to block:", blockNumber-1)
|
| 876 |
+
s.CleanTrustedState()
|
| 877 |
+
return s.resetState(blockNumber - 1)
|
| 878 |
+
}
|
| 879 |
+
func (s *ClientSynchronizer) detectedReorgBadBlockExecuteReset(lastEthBlockSynced *state.Block, badBlockNumber uint64) (bool, *state.Block, error) {
|
| 880 |
+
firstBlockOK, err := s.checkReorg(lastEthBlockSynced, nil)
|
| 881 |
+
if err != nil {
|
| 882 |
+
log.Warnf("error checking reorgs. using badBlock detected: %d Err: %v", badBlockNumber, err)
|
| 883 |
+
firstBlockOK = nil
|
| 884 |
+
}
|
| 885 |
+
if firstBlockOK != nil && firstBlockOK.BlockNumber >= badBlockNumber {
|
| 886 |
+
log.Warnf("Reorg detected firstBlockOk: %d. But oldest bad block detected: %d", firstBlockOK.BlockNumber, badBlockNumber)
|
| 887 |
+
firstBlockOK = nil
|
| 888 |
+
}
|
| 889 |
+
// We already known a bad block, reset from there
|
| 890 |
+
if firstBlockOK == nil {
|
| 891 |
+
firstBlockOK, err = s.state.GetPreviousBlockToBlockNumber(s.ctx, badBlockNumber, nil)
|
| 892 |
+
if err != nil {
|
| 893 |
+
log.Errorf("error getting previous block %d from db. Can't execute REORG. Error: %v", badBlockNumber, err)
|
| 894 |
+
return false, lastEthBlockSynced, err
|
| 895 |
+
}
|
| 896 |
+
}
|
| 897 |
+
newFirstBlock, err := s.executeReorgFromFirstValidBlock(lastEthBlockSynced, firstBlockOK)
|
| 898 |
+
if err != nil {
|
| 899 |
+
log.Errorf("error executing reorg. Retrying... Err: %v", err)
|
| 900 |
+
return false, lastEthBlockSynced, fmt.Errorf("error executing reorg. Err: %w", err)
|
| 901 |
+
}
|
| 902 |
+
return true, newFirstBlock, nil
|
| 903 |
+
}
|
| 904 |
+
|
| 905 |
+
// checkReorgAndExecuteReset function will check if there is a reorg and execute the reset
|
| 906 |
+
// returns true is reset have been done
|
| 907 |
+
func (s *ClientSynchronizer) checkReorgAndExecuteReset(lastEthBlockSynced *state.Block) (bool, *state.Block, error) {
|
| 908 |
+
var err error
|
| 909 |
+
|
| 910 |
+
block, err := s.checkReorg(lastEthBlockSynced, nil)
|
| 911 |
+
if err != nil {
|
| 912 |
+
log.Errorf("error checking reorgs. Retrying... Err: %v", err)
|
| 913 |
+
return false, lastEthBlockSynced, fmt.Errorf("error checking reorgs")
|
| 914 |
+
}
|
| 915 |
+
if block != nil {
|
| 916 |
+
newFirstBlock, err := s.executeReorgFromFirstValidBlock(lastEthBlockSynced, block)
|
| 917 |
+
if err != nil {
|
| 918 |
+
log.Errorf("error executing reorg. Retrying... Err: %v", err)
|
| 919 |
+
return false, lastEthBlockSynced, fmt.Errorf("error executing reorg. Err: %w", err)
|
| 920 |
+
}
|
| 921 |
+
return true, newFirstBlock, nil
|
| 922 |
+
}
|
| 923 |
+
|
| 924 |
+
return false, lastEthBlockSynced, nil
|
| 925 |
+
}
|
| 926 |
+
|
| 927 |
+
func (s *ClientSynchronizer) executeReorgFromFirstValidBlock(lastEthBlockSynced *state.Block, firstValidBlock *state.Block) (*state.Block, error) {
|
| 928 |
+
log.Infof("reorg detected. Resetting the state from block %v to block %v", lastEthBlockSynced.BlockNumber, firstValidBlock.BlockNumber)
|
| 929 |
+
s.CleanTrustedState()
|
| 930 |
+
err := s.resetState(firstValidBlock.BlockNumber)
|
| 931 |
+
if err != nil {
|
| 932 |
+
log.Errorf("error resetting the state to a previous block. Retrying... Err: %s", err.Error())
|
| 933 |
+
return nil, fmt.Errorf("error resetting the state to a previous block. Err: %w", err)
|
| 934 |
+
}
|
| 935 |
+
newLastBlock, err := s.state.GetLastBlock(s.ctx, nil)
|
| 936 |
+
if err != nil {
|
| 937 |
+
log.Warnf("error getting last block synced from db, returning expected block %d. Error: %v", firstValidBlock.BlockNumber, err)
|
| 938 |
+
return firstValidBlock, nil
|
| 939 |
+
}
|
| 940 |
+
if newLastBlock.BlockNumber != firstValidBlock.BlockNumber {
|
| 941 |
+
log.Warnf("Doesnt match LastBlock on State and expecting one after a resetState. The block in state is %d and the expected block is %d", newLastBlock.BlockNumber,
|
| 942 |
+
firstValidBlock.BlockNumber)
|
| 943 |
+
return firstValidBlock, nil
|
| 944 |
+
}
|
| 945 |
+
return newLastBlock, nil
|
| 946 |
+
}
|
| 947 |
+
|
| 948 |
+
func (s *ClientSynchronizer) checkReorg(latestBlock *state.Block, syncedBlock *etherman.Block) (*state.Block, error) {
|
| 949 |
+
if latestBlock == nil {
|
| 950 |
+
err := fmt.Errorf("lastEthBlockSynced is nil calling checkReorgAndExecuteReset")
|
| 951 |
+
log.Errorf("%s, it never have to happens", err.Error())
|
| 952 |
+
return nil, err
|
| 953 |
+
}
|
| 954 |
+
block, errReturnedReorgFunction := s.newCheckReorg(latestBlock, syncedBlock)
|
| 955 |
+
if s.asyncL1BlockChecker != nil {
|
| 956 |
+
return s.asyncL1BlockChecker.CheckReorgWrapper(s.ctx, block, errReturnedReorgFunction)
|
| 957 |
+
}
|
| 958 |
+
return block, errReturnedReorgFunction
|
| 959 |
+
}
|
| 960 |
+
|
| 961 |
/*
|
| 962 |
This function will check if there is a reorg.
|
| 963 |
As input param needs the last ethereum block synced. Retrieve the block info from the blockchain
|
|
|
|
| 966 |
must be reverted. Then, check the previous ethereum block synced, get block info from the blockchain and check
|
| 967 |
hash and has parent. This operation has to be done until a match is found.
|
| 968 |
*/
|
| 969 |
+
|
| 970 |
+
func (s *ClientSynchronizer) newCheckReorg(latestStoredBlock *state.Block, syncedBlock *etherman.Block) (*state.Block, error) {
|
| 971 |
// This function only needs to worry about reorgs if some of the reorganized blocks contained rollup info.
|
| 972 |
+
latestStoredEthBlock := *latestStoredBlock
|
| 973 |
+
reorgedBlock := *latestStoredBlock
|
| 974 |
var depth uint64
|
| 975 |
+
block := syncedBlock
|
| 976 |
for {
|
| 977 |
+
if block == nil {
|
| 978 |
+
log.Infof("[checkReorg function] Checking Block %d in L1", reorgedBlock.BlockNumber)
|
| 979 |
+
b, err := s.etherMan.EthBlockByNumber(s.ctx, reorgedBlock.BlockNumber)
|
| 980 |
+
if err != nil {
|
| 981 |
+
log.Errorf("error getting latest block synced from blockchain. Block: %d, error: %v", reorgedBlock.BlockNumber, err)
|
| 982 |
+
return nil, err
|
| 983 |
+
}
|
| 984 |
+
block = ðerman.Block{
|
| 985 |
+
BlockNumber: b.Number().Uint64(),
|
| 986 |
+
BlockHash: b.Hash(),
|
| 987 |
+
ParentHash: b.ParentHash(),
|
| 988 |
+
}
|
| 989 |
+
if block.BlockNumber != reorgedBlock.BlockNumber {
|
| 990 |
+
err := fmt.Errorf("wrong ethereum block retrieved from blockchain. Block numbers don't match. BlockNumber stored: %d. BlockNumber retrieved: %d",
|
| 991 |
+
reorgedBlock.BlockNumber, block.BlockNumber)
|
| 992 |
+
log.Error("error: ", err)
|
| 993 |
+
return nil, err
|
| 994 |
+
}
|
| 995 |
+
} else {
|
| 996 |
+
log.Infof("[checkReorg function] Using block %d from GetRollupInfoByBlockRange", block.BlockNumber)
|
| 997 |
}
|
| 998 |
+
log.Infof("[checkReorg function] BlockNumber: %d BlockHash got from L1 provider: %s", block.BlockNumber, block.BlockHash.String())
|
| 999 |
+
log.Infof("[checkReorg function] reorgedBlockNumber: %d reorgedBlockHash already synced: %s", reorgedBlock.BlockNumber, reorgedBlock.BlockHash.String())
|
| 1000 |
+
|
| 1001 |
// Compare hashes
|
| 1002 |
+
if (block.BlockHash != reorgedBlock.BlockHash || block.ParentHash != reorgedBlock.ParentHash) && reorgedBlock.BlockNumber > s.genesis.RollupBlockNumber {
|
| 1003 |
+
log.Infof("checkReorg: Bad block %d hashOk %t parentHashOk %t", reorgedBlock.BlockNumber, block.BlockHash == reorgedBlock.BlockHash, block.ParentHash == reorgedBlock.ParentHash)
|
| 1004 |
+
log.Debug("[checkReorg function] => latestBlockNumber: ", reorgedBlock.BlockNumber)
|
| 1005 |
+
log.Debug("[checkReorg function] => latestBlockHash: ", reorgedBlock.BlockHash)
|
| 1006 |
+
log.Debug("[checkReorg function] => latestBlockHashParent: ", reorgedBlock.ParentHash)
|
| 1007 |
+
log.Debug("[checkReorg function] => BlockNumber: ", reorgedBlock.BlockNumber, block.BlockNumber)
|
| 1008 |
+
log.Debug("[checkReorg function] => BlockHash: ", block.BlockHash)
|
| 1009 |
+
log.Debug("[checkReorg function] => BlockHashParent: ", block.ParentHash)
|
| 1010 |
depth++
|
| 1011 |
log.Debug("REORG: Looking for the latest correct ethereum block. Depth: ", depth)
|
| 1012 |
// Reorg detected. Getting previous block
|
|
|
|
| 1015 |
log.Errorf("error creating db transaction to get prevoius blocks")
|
| 1016 |
return nil, err
|
| 1017 |
}
|
| 1018 |
+
lb, err := s.state.GetPreviousBlock(s.ctx, depth, dbTx)
|
| 1019 |
errC := dbTx.Commit(s.ctx)
|
| 1020 |
if errC != nil {
|
| 1021 |
log.Errorf("error committing dbTx, err: %v", errC)
|
|
|
|
| 1028 |
return nil, errC
|
| 1029 |
}
|
| 1030 |
if errors.Is(err, state.ErrNotFound) {
|
| 1031 |
+
log.Warn("error checking reorg: previous block not found in db. Reorg reached the genesis block: %v.Genesis block can't be reorged, using genesis block as starting point. Error: %v", reorgedBlock, err)
|
| 1032 |
+
return &reorgedBlock, nil
|
| 1033 |
} else if err != nil {
|
| 1034 |
+
log.Error("error getting previousBlock from db. Error: ", err)
|
| 1035 |
return nil, err
|
| 1036 |
}
|
| 1037 |
+
reorgedBlock = *lb
|
| 1038 |
} else {
|
| 1039 |
+
log.Debugf("checkReorg: Block %d hashOk %t parentHashOk %t", reorgedBlock.BlockNumber, block.BlockHash == reorgedBlock.BlockHash, block.ParentHash == reorgedBlock.ParentHash)
|
| 1040 |
break
|
| 1041 |
}
|
| 1042 |
+
// This forces to get the block from L1 in the next iteration of the loop
|
| 1043 |
+
block = nil
|
| 1044 |
}
|
| 1045 |
+
if latestStoredEthBlock.BlockHash != reorgedBlock.BlockHash {
|
| 1046 |
+
latestStoredBlock = &reorgedBlock
|
| 1047 |
+
log.Info("Reorg detected in block: ", latestStoredEthBlock.BlockNumber, " last block OK: ", latestStoredBlock.BlockNumber)
|
| 1048 |
+
return latestStoredBlock, nil
|
| 1049 |
}
|
| 1050 |
+
log.Debugf("No reorg detected in block: %d. BlockHash: %s", latestStoredEthBlock.BlockNumber, latestStoredEthBlock.BlockHash.String())
|
| 1051 |
return nil, nil
|
| 1052 |
}
|
| 1053 |
|
|
@@ -2,6 +2,7 @@
|
|
| 2 |
|
| 3 |
import (
|
| 4 |
context "context"
|
|
|
|
| 5 |
"math/big"
|
| 6 |
"testing"
|
| 7 |
"time"
|
|
@@ -18,6 +19,7 @@
|
|
| 18 |
syncMocks "github.com/0xPolygonHermez/zkevm-node/synchronizer/mocks"
|
| 19 |
"github.com/ethereum/go-ethereum/common"
|
| 20 |
ethTypes "github.com/ethereum/go-ethereum/core/types"
|
|
|
|
| 21 |
"github.com/jackc/pgx/v4"
|
| 22 |
"github.com/stretchr/testify/assert"
|
| 23 |
"github.com/stretchr/testify/mock"
|
|
@@ -32,12 +34,13 @@
|
|
| 32 |
)
|
| 33 |
|
| 34 |
type mocks struct {
|
| 35 |
-
Etherman
|
| 36 |
-
State
|
| 37 |
-
Pool
|
| 38 |
-
EthTxManager
|
| 39 |
-
DbTx
|
| 40 |
-
ZKEVMClient
|
|
|
|
| 41 |
//EventLog *eventLogMock
|
| 42 |
}
|
| 43 |
|
|
@@ -47,7 +50,7 @@
|
|
| 47 |
func TestGivenPermissionlessNodeWhenSyncronizeAgainSameBatchThenUseTheOneInMemoryInstaeadOfGettingFromDb(t *testing.T) {
|
| 48 |
genesis, cfg, m := setupGenericTest(t)
|
| 49 |
ethermanForL1 := []syncinterfaces.EthermanFullInterface{m.Etherman}
|
| 50 |
-
syncInterface, err := NewSynchronizer(false, m.Etherman, ethermanForL1, m.State, m.Pool, m.EthTxManager, m.ZKEVMClient, nil, *genesis, *cfg, false)
|
| 51 |
require.NoError(t, err)
|
| 52 |
sync, ok := syncInterface.(*ClientSynchronizer)
|
| 53 |
require.EqualValues(t, true, ok, "Can't convert to underlaying struct the interface of syncronizer")
|
|
@@ -87,7 +90,7 @@
|
|
| 87 |
func TestGivenPermissionlessNodeWhenSyncronizeFirstTimeABatchThenStoreItInALocalVar(t *testing.T) {
|
| 88 |
genesis, cfg, m := setupGenericTest(t)
|
| 89 |
ethermanForL1 := []syncinterfaces.EthermanFullInterface{m.Etherman}
|
| 90 |
-
syncInterface, err := NewSynchronizer(false, m.Etherman, ethermanForL1, m.State, m.Pool, m.EthTxManager, m.ZKEVMClient, nil, *genesis, *cfg, false)
|
| 91 |
require.NoError(t, err)
|
| 92 |
sync, ok := syncInterface.(*ClientSynchronizer)
|
| 93 |
require.EqualValues(t, true, ok, "Can't convert to underlaying struct the interface of syncronizer")
|
|
@@ -119,12 +122,16 @@
|
|
| 119 |
// but it used a feature that is not implemented in new one that is asking beyond the last block on L1
|
| 120 |
func TestForcedBatchEtrog(t *testing.T) {
|
| 121 |
genesis := state.Genesis{
|
| 122 |
-
|
| 123 |
}
|
| 124 |
cfg := Config{
|
| 125 |
SyncInterval: cfgTypes.Duration{Duration: 1 * time.Second},
|
| 126 |
SyncChunkSize: 10,
|
| 127 |
L1SynchronizationMode: SequentialMode,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 128 |
}
|
| 129 |
|
| 130 |
m := mocks{
|
|
@@ -135,7 +142,7 @@
|
|
| 135 |
ZKEVMClient: mock_syncinterfaces.NewZKEVMClientInterface(t),
|
| 136 |
}
|
| 137 |
ethermanForL1 := []syncinterfaces.EthermanFullInterface{m.Etherman}
|
| 138 |
-
sync, err := NewSynchronizer(false, m.Etherman, ethermanForL1, m.State, m.Pool, m.EthTxManager, m.ZKEVMClient, nil, genesis, cfg, false)
|
| 139 |
require.NoError(t, err)
|
| 140 |
|
| 141 |
// state preparation
|
|
@@ -151,17 +158,21 @@
|
|
| 151 |
Run(func(args mock.Arguments) {
|
| 152 |
ctx := args[0].(context.Context)
|
| 153 |
parentHash := common.HexToHash("0x111")
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
|
|
|
|
|
|
|
|
|
| 157 |
|
| 158 |
m.State.
|
| 159 |
On("GetForkIDByBatchNumber", mock.Anything).
|
| 160 |
Return(uint64(7), nil).
|
| 161 |
Maybe()
|
|
|
|
| 162 |
m.State.
|
| 163 |
On("GetLastBlock", ctx, m.DbTx).
|
| 164 |
-
Return(
|
| 165 |
Once()
|
| 166 |
|
| 167 |
m.State.
|
|
@@ -197,14 +208,14 @@
|
|
| 197 |
Return(nil)
|
| 198 |
|
| 199 |
m.Etherman.
|
| 200 |
-
On("EthBlockByNumber", ctx,
|
| 201 |
-
Return(
|
| 202 |
-
|
| 203 |
|
| 204 |
-
|
| 205 |
m.Etherman.
|
| 206 |
On("HeaderByNumber", mock.Anything, n).
|
| 207 |
-
Return(
|
| 208 |
Once()
|
| 209 |
|
| 210 |
t := time.Date(2024, 1, 1, 1, 0, 0, 0, time.UTC)
|
|
@@ -223,7 +234,7 @@
|
|
| 223 |
}
|
| 224 |
|
| 225 |
forceb := []etherman.ForcedBatch{{
|
| 226 |
-
BlockNumber:
|
| 227 |
ForcedBatchNumber: 1,
|
| 228 |
Sequencer: sequencedBatch.Coinbase,
|
| 229 |
GlobalExitRoot: sequencedBatch.PolygonRollupBaseEtrogBatchData.ForcedGlobalExitRoot,
|
|
@@ -231,16 +242,21 @@
|
|
| 231 |
ForcedAt: time.Unix(int64(sequencedBatch.PolygonRollupBaseEtrogBatchData.ForcedTimestamp), 0),
|
| 232 |
}}
|
| 233 |
|
| 234 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 235 |
BlockNumber: 1,
|
| 236 |
ReceivedAt: t,
|
| 237 |
-
BlockHash:
|
| 238 |
SequencedBatches: [][]etherman.SequencedBatch{{sequencedBatch}},
|
| 239 |
ForcedBatches: forceb,
|
| 240 |
}
|
| 241 |
-
blocks := []etherman.Block{
|
| 242 |
order := map[common.Hash][]etherman.Order{
|
| 243 |
-
|
| 244 |
{
|
| 245 |
Name: etherman.ForcedBatchesOrder,
|
| 246 |
Pos: 0,
|
|
@@ -252,9 +268,11 @@
|
|
| 252 |
},
|
| 253 |
}
|
| 254 |
|
| 255 |
-
fromBlock :=
|
| 256 |
toBlock := fromBlock + cfg.SyncChunkSize
|
| 257 |
-
|
|
|
|
|
|
|
| 258 |
m.Etherman.
|
| 259 |
On("GetRollupInfoByBlockRange", mock.Anything, fromBlock, &toBlock).
|
| 260 |
Return(blocks, order, nil).
|
|
@@ -270,10 +288,11 @@
|
|
| 270 |
Once()
|
| 271 |
|
| 272 |
stateBlock := &state.Block{
|
| 273 |
-
BlockNumber:
|
| 274 |
-
BlockHash:
|
| 275 |
-
ParentHash:
|
| 276 |
-
ReceivedAt:
|
|
|
|
| 277 |
}
|
| 278 |
|
| 279 |
executionResponse := executor.ProcessBatchResponseV2{
|
|
@@ -285,13 +304,18 @@
|
|
| 285 |
Return(&executionResponse, nil).
|
| 286 |
Times(1)
|
| 287 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 288 |
m.State.
|
| 289 |
On("AddBlock", ctx, stateBlock, m.DbTx).
|
| 290 |
Return(nil).
|
| 291 |
Once()
|
| 292 |
|
| 293 |
fb := []state.ForcedBatch{{
|
| 294 |
-
BlockNumber:
|
| 295 |
ForcedBatchNumber: 1,
|
| 296 |
Sequencer: sequencedBatch.Coinbase,
|
| 297 |
GlobalExitRoot: sequencedBatch.PolygonRollupBaseEtrogBatchData.ForcedGlobalExitRoot,
|
|
@@ -326,7 +350,7 @@
|
|
| 326 |
BatchNumber: sequencedBatch.BatchNumber,
|
| 327 |
TxHash: sequencedBatch.TxHash,
|
| 328 |
Coinbase: sequencedBatch.Coinbase,
|
| 329 |
-
BlockNumber:
|
| 330 |
TimestampBatchEtrog: &t,
|
| 331 |
L1InfoRoot: &forcedGER,
|
| 332 |
}
|
|
@@ -372,12 +396,13 @@
|
|
| 372 |
// but it used a feature that is not implemented in new one that is asking beyond the last block on L1
|
| 373 |
func TestSequenceForcedBatchIncaberry(t *testing.T) {
|
| 374 |
genesis := state.Genesis{
|
| 375 |
-
|
| 376 |
}
|
| 377 |
cfg := Config{
|
| 378 |
SyncInterval: cfgTypes.Duration{Duration: 1 * time.Second},
|
| 379 |
SyncChunkSize: 10,
|
| 380 |
L1SynchronizationMode: SequentialMode,
|
|
|
|
| 381 |
}
|
| 382 |
|
| 383 |
m := mocks{
|
|
@@ -388,7 +413,7 @@
|
|
| 388 |
ZKEVMClient: mock_syncinterfaces.NewZKEVMClientInterface(t),
|
| 389 |
}
|
| 390 |
ethermanForL1 := []syncinterfaces.EthermanFullInterface{m.Etherman}
|
| 391 |
-
sync, err := NewSynchronizer(true, m.Etherman, ethermanForL1, m.State, m.Pool, m.EthTxManager, m.ZKEVMClient, nil, genesis, cfg, false)
|
| 392 |
require.NoError(t, err)
|
| 393 |
|
| 394 |
// state preparation
|
|
@@ -398,21 +423,20 @@
|
|
| 398 |
Run(func(args mock.Arguments) {
|
| 399 |
ctx := args[0].(context.Context)
|
| 400 |
parentHash := common.HexToHash("0x111")
|
| 401 |
-
|
| 402 |
-
|
| 403 |
-
|
|
|
|
|
|
|
|
|
|
| 404 |
m.State.
|
| 405 |
On("GetForkIDByBatchNumber", mock.Anything).
|
| 406 |
Return(uint64(1), nil).
|
| 407 |
Maybe()
|
| 408 |
-
m.State.
|
| 409 |
-
On("GetForkIDByBlockNumber", mock.Anything).
|
| 410 |
-
Return(uint64(1), nil).
|
| 411 |
-
Maybe()
|
| 412 |
|
| 413 |
m.State.
|
| 414 |
On("GetLastBlock", ctx, m.DbTx).
|
| 415 |
-
Return(
|
| 416 |
Once()
|
| 417 |
|
| 418 |
m.State.
|
|
@@ -450,15 +474,15 @@
|
|
| 450 |
Return(nil).
|
| 451 |
Once()
|
| 452 |
|
|
|
|
| 453 |
m.Etherman.
|
| 454 |
-
On("
|
| 455 |
-
Return(
|
| 456 |
Once()
|
| 457 |
|
| 458 |
-
var n *big.Int
|
| 459 |
m.Etherman.
|
| 460 |
-
On("
|
| 461 |
-
Return(
|
| 462 |
Once()
|
| 463 |
|
| 464 |
sequencedForceBatch := etherman.SequencedForceBatch{
|
|
@@ -474,7 +498,7 @@
|
|
| 474 |
}
|
| 475 |
|
| 476 |
forceb := []etherman.ForcedBatch{{
|
| 477 |
-
BlockNumber:
|
| 478 |
ForcedBatchNumber: 1,
|
| 479 |
Sequencer: sequencedForceBatch.Coinbase,
|
| 480 |
GlobalExitRoot: sequencedForceBatch.PolygonRollupBaseEtrogBatchData.ForcedGlobalExitRoot,
|
|
@@ -482,14 +506,21 @@
|
|
| 482 |
ForcedAt: time.Unix(int64(sequencedForceBatch.PolygonRollupBaseEtrogBatchData.ForcedTimestamp), 0),
|
| 483 |
}}
|
| 484 |
|
| 485 |
-
|
| 486 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 487 |
SequencedForceBatches: [][]etherman.SequencedForceBatch{{sequencedForceBatch}},
|
| 488 |
ForcedBatches: forceb,
|
| 489 |
}
|
| 490 |
-
blocks := []etherman.Block{
|
| 491 |
order := map[common.Hash][]etherman.Order{
|
| 492 |
-
|
| 493 |
{
|
| 494 |
Name: etherman.ForcedBatchesOrder,
|
| 495 |
Pos: 0,
|
|
@@ -501,24 +532,32 @@
|
|
| 501 |
},
|
| 502 |
}
|
| 503 |
|
| 504 |
-
fromBlock :=
|
| 505 |
toBlock := fromBlock + cfg.SyncChunkSize
|
| 506 |
-
|
|
|
|
|
|
|
| 507 |
m.Etherman.
|
| 508 |
On("GetRollupInfoByBlockRange", ctx, fromBlock, &toBlock).
|
| 509 |
Return(blocks, order, nil).
|
| 510 |
Once()
|
| 511 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 512 |
m.State.
|
| 513 |
On("BeginStateTransaction", ctx).
|
| 514 |
Return(m.DbTx, nil).
|
| 515 |
Once()
|
| 516 |
|
| 517 |
stateBlock := &state.Block{
|
| 518 |
-
BlockNumber:
|
| 519 |
-
BlockHash:
|
| 520 |
-
ParentHash:
|
| 521 |
-
ReceivedAt:
|
|
|
|
| 522 |
}
|
| 523 |
|
| 524 |
m.State.
|
|
@@ -526,8 +565,13 @@
|
|
| 526 |
Return(nil).
|
| 527 |
Once()
|
| 528 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 529 |
fb := []state.ForcedBatch{{
|
| 530 |
-
BlockNumber:
|
| 531 |
ForcedBatchNumber: 1,
|
| 532 |
Sequencer: sequencedForceBatch.Coinbase,
|
| 533 |
GlobalExitRoot: sequencedForceBatch.PolygonRollupBaseEtrogBatchData.ForcedGlobalExitRoot,
|
|
@@ -559,7 +603,7 @@
|
|
| 559 |
processingContext := state.ProcessingContext{
|
| 560 |
BatchNumber: sequencedForceBatch.BatchNumber,
|
| 561 |
Coinbase: sequencedForceBatch.Coinbase,
|
| 562 |
-
Timestamp:
|
| 563 |
GlobalExitRoot: sequencedForceBatch.PolygonRollupBaseEtrogBatchData.ForcedGlobalExitRoot,
|
| 564 |
ForcedBatchNum: &f,
|
| 565 |
BatchL2Data: &sequencedForceBatch.PolygonRollupBaseEtrogBatchData.Transactions,
|
|
@@ -574,7 +618,7 @@
|
|
| 574 |
TxHash: sequencedForceBatch.TxHash,
|
| 575 |
Coinbase: sequencedForceBatch.Coinbase,
|
| 576 |
SequencerAddr: sequencedForceBatch.Coinbase,
|
| 577 |
-
BlockNumber:
|
| 578 |
}
|
| 579 |
|
| 580 |
m.State.
|
|
@@ -598,7 +642,10 @@
|
|
| 598 |
|
| 599 |
m.DbTx.
|
| 600 |
On("Commit", ctx).
|
| 601 |
-
Run(func(args mock.Arguments) {
|
|
|
|
|
|
|
|
|
|
| 602 |
Return(nil).
|
| 603 |
Once()
|
| 604 |
}).
|
|
@@ -611,12 +658,13 @@
|
|
| 611 |
|
| 612 |
func setupGenericTest(t *testing.T) (*state.Genesis, *Config, *mocks) {
|
| 613 |
genesis := state.Genesis{
|
| 614 |
-
|
| 615 |
}
|
| 616 |
cfg := Config{
|
| 617 |
SyncInterval: cfgTypes.Duration{Duration: 1 * time.Second},
|
| 618 |
SyncChunkSize: 10,
|
| 619 |
L1SynchronizationMode: SequentialMode,
|
|
|
|
| 620 |
L1ParallelSynchronization: L1ParallelSynchronizationConfig{
|
| 621 |
MaxClients: 2,
|
| 622 |
MaxPendingNoProcessedBlocks: 2,
|
|
@@ -631,12 +679,13 @@
|
|
| 631 |
}
|
| 632 |
|
| 633 |
m := mocks{
|
| 634 |
-
Etherman:
|
| 635 |
-
State:
|
| 636 |
-
Pool:
|
| 637 |
-
DbTx:
|
| 638 |
-
ZKEVMClient:
|
| 639 |
-
|
|
|
|
| 640 |
//EventLog: newEventLogMock(t),
|
| 641 |
}
|
| 642 |
return &genesis, &cfg, &m
|
|
@@ -870,3 +919,1365 @@
|
|
| 870 |
Return(nil).
|
| 871 |
Once()
|
| 872 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
|
| 3 |
import (
|
| 4 |
context "context"
|
| 5 |
+
"math"
|
| 6 |
"math/big"
|
| 7 |
"testing"
|
| 8 |
"time"
|
|
|
|
| 19 |
syncMocks "github.com/0xPolygonHermez/zkevm-node/synchronizer/mocks"
|
| 20 |
"github.com/ethereum/go-ethereum/common"
|
| 21 |
ethTypes "github.com/ethereum/go-ethereum/core/types"
|
| 22 |
+
"github.com/ethereum/go-ethereum/rpc"
|
| 23 |
"github.com/jackc/pgx/v4"
|
| 24 |
"github.com/stretchr/testify/assert"
|
| 25 |
"github.com/stretchr/testify/mock"
|
|
|
|
| 34 |
)
|
| 35 |
|
| 36 |
type mocks struct {
|
| 37 |
+
Etherman *mock_syncinterfaces.EthermanFullInterface
|
| 38 |
+
State *mock_syncinterfaces.StateFullInterface
|
| 39 |
+
Pool *mock_syncinterfaces.PoolInterface
|
| 40 |
+
EthTxManager *mock_syncinterfaces.EthTxManager
|
| 41 |
+
DbTx *syncMocks.DbTxMock
|
| 42 |
+
ZKEVMClient *mock_syncinterfaces.ZKEVMClientInterface
|
| 43 |
+
zkEVMClientEthereumCompatible *mock_syncinterfaces.ZKEVMClientEthereumCompatibleInterface
|
| 44 |
//EventLog *eventLogMock
|
| 45 |
}
|
| 46 |
|
|
|
|
| 50 |
func TestGivenPermissionlessNodeWhenSyncronizeAgainSameBatchThenUseTheOneInMemoryInstaeadOfGettingFromDb(t *testing.T) {
|
| 51 |
genesis, cfg, m := setupGenericTest(t)
|
| 52 |
ethermanForL1 := []syncinterfaces.EthermanFullInterface{m.Etherman}
|
| 53 |
+
syncInterface, err := NewSynchronizer(false, m.Etherman, ethermanForL1, m.State, m.Pool, m.EthTxManager, m.ZKEVMClient, m.zkEVMClientEthereumCompatible, nil, *genesis, *cfg, false)
|
| 54 |
require.NoError(t, err)
|
| 55 |
sync, ok := syncInterface.(*ClientSynchronizer)
|
| 56 |
require.EqualValues(t, true, ok, "Can't convert to underlaying struct the interface of syncronizer")
|
|
|
|
| 90 |
func TestGivenPermissionlessNodeWhenSyncronizeFirstTimeABatchThenStoreItInALocalVar(t *testing.T) {
|
| 91 |
genesis, cfg, m := setupGenericTest(t)
|
| 92 |
ethermanForL1 := []syncinterfaces.EthermanFullInterface{m.Etherman}
|
| 93 |
+
syncInterface, err := NewSynchronizer(false, m.Etherman, ethermanForL1, m.State, m.Pool, m.EthTxManager, m.ZKEVMClient, m.zkEVMClientEthereumCompatible, nil, *genesis, *cfg, false)
|
| 94 |
require.NoError(t, err)
|
| 95 |
sync, ok := syncInterface.(*ClientSynchronizer)
|
| 96 |
require.EqualValues(t, true, ok, "Can't convert to underlaying struct the interface of syncronizer")
|
|
|
|
| 122 |
// but it used a feature that is not implemented in new one that is asking beyond the last block on L1
|
| 123 |
func TestForcedBatchEtrog(t *testing.T) {
|
| 124 |
genesis := state.Genesis{
|
| 125 |
+
RollupBlockNumber: uint64(0),
|
| 126 |
}
|
| 127 |
cfg := Config{
|
| 128 |
SyncInterval: cfgTypes.Duration{Duration: 1 * time.Second},
|
| 129 |
SyncChunkSize: 10,
|
| 130 |
L1SynchronizationMode: SequentialMode,
|
| 131 |
+
SyncBlockProtection: "latest",
|
| 132 |
+
L1BlockCheck: L1BlockCheckConfig{
|
| 133 |
+
Enable: false,
|
| 134 |
+
},
|
| 135 |
}
|
| 136 |
|
| 137 |
m := mocks{
|
|
|
|
| 142 |
ZKEVMClient: mock_syncinterfaces.NewZKEVMClientInterface(t),
|
| 143 |
}
|
| 144 |
ethermanForL1 := []syncinterfaces.EthermanFullInterface{m.Etherman}
|
| 145 |
+
sync, err := NewSynchronizer(false, m.Etherman, ethermanForL1, m.State, m.Pool, m.EthTxManager, m.ZKEVMClient, m.zkEVMClientEthereumCompatible, nil, genesis, cfg, false)
|
| 146 |
require.NoError(t, err)
|
| 147 |
|
| 148 |
// state preparation
|
|
|
|
| 158 |
Run(func(args mock.Arguments) {
|
| 159 |
ctx := args[0].(context.Context)
|
| 160 |
parentHash := common.HexToHash("0x111")
|
| 161 |
+
ethHeader0 := ðTypes.Header{Number: big.NewInt(0), ParentHash: parentHash}
|
| 162 |
+
ethBlock0 := ethTypes.NewBlockWithHeader(ethHeader0)
|
| 163 |
+
ethHeader1 := ðTypes.Header{Number: big.NewInt(1), ParentHash: ethBlock0.Hash()}
|
| 164 |
+
ethBlock1 := ethTypes.NewBlockWithHeader(ethHeader1)
|
| 165 |
+
lastBlock0 := &state.Block{BlockHash: ethBlock0.Hash(), BlockNumber: ethBlock0.Number().Uint64(), ParentHash: ethBlock0.ParentHash()}
|
| 166 |
+
lastBlock1 := &state.Block{BlockHash: ethBlock1.Hash(), BlockNumber: ethBlock1.Number().Uint64(), ParentHash: ethBlock1.ParentHash()}
|
| 167 |
|
| 168 |
m.State.
|
| 169 |
On("GetForkIDByBatchNumber", mock.Anything).
|
| 170 |
Return(uint64(7), nil).
|
| 171 |
Maybe()
|
| 172 |
+
|
| 173 |
m.State.
|
| 174 |
On("GetLastBlock", ctx, m.DbTx).
|
| 175 |
+
Return(lastBlock0, nil).
|
| 176 |
Once()
|
| 177 |
|
| 178 |
m.State.
|
|
|
|
| 208 |
Return(nil)
|
| 209 |
|
| 210 |
m.Etherman.
|
| 211 |
+
On("EthBlockByNumber", ctx, lastBlock0.BlockNumber).
|
| 212 |
+
Return(ethBlock0, nil).
|
| 213 |
+
Times(2)
|
| 214 |
|
| 215 |
+
n := big.NewInt(rpc.LatestBlockNumber.Int64())
|
| 216 |
m.Etherman.
|
| 217 |
On("HeaderByNumber", mock.Anything, n).
|
| 218 |
+
Return(ethHeader1, nil).
|
| 219 |
Once()
|
| 220 |
|
| 221 |
t := time.Date(2024, 1, 1, 1, 0, 0, 0, time.UTC)
|
|
|
|
| 234 |
}
|
| 235 |
|
| 236 |
forceb := []etherman.ForcedBatch{{
|
| 237 |
+
BlockNumber: lastBlock1.BlockNumber,
|
| 238 |
ForcedBatchNumber: 1,
|
| 239 |
Sequencer: sequencedBatch.Coinbase,
|
| 240 |
GlobalExitRoot: sequencedBatch.PolygonRollupBaseEtrogBatchData.ForcedGlobalExitRoot,
|
|
|
|
| 242 |
ForcedAt: time.Unix(int64(sequencedBatch.PolygonRollupBaseEtrogBatchData.ForcedTimestamp), 0),
|
| 243 |
}}
|
| 244 |
|
| 245 |
+
ethermanBlock0 := etherman.Block{
|
| 246 |
+
BlockNumber: 0,
|
| 247 |
+
ReceivedAt: t,
|
| 248 |
+
BlockHash: ethBlock0.Hash(),
|
| 249 |
+
}
|
| 250 |
+
ethermanBlock1 := etherman.Block{
|
| 251 |
BlockNumber: 1,
|
| 252 |
ReceivedAt: t,
|
| 253 |
+
BlockHash: ethBlock1.Hash(),
|
| 254 |
SequencedBatches: [][]etherman.SequencedBatch{{sequencedBatch}},
|
| 255 |
ForcedBatches: forceb,
|
| 256 |
}
|
| 257 |
+
blocks := []etherman.Block{ethermanBlock0, ethermanBlock1}
|
| 258 |
order := map[common.Hash][]etherman.Order{
|
| 259 |
+
ethBlock1.Hash(): {
|
| 260 |
{
|
| 261 |
Name: etherman.ForcedBatchesOrder,
|
| 262 |
Pos: 0,
|
|
|
|
| 268 |
},
|
| 269 |
}
|
| 270 |
|
| 271 |
+
fromBlock := ethBlock0.NumberU64()
|
| 272 |
toBlock := fromBlock + cfg.SyncChunkSize
|
| 273 |
+
if toBlock > ethBlock1.NumberU64() {
|
| 274 |
+
toBlock = ethBlock1.NumberU64()
|
| 275 |
+
}
|
| 276 |
m.Etherman.
|
| 277 |
On("GetRollupInfoByBlockRange", mock.Anything, fromBlock, &toBlock).
|
| 278 |
Return(blocks, order, nil).
|
|
|
|
| 288 |
Once()
|
| 289 |
|
| 290 |
stateBlock := &state.Block{
|
| 291 |
+
BlockNumber: ethermanBlock1.BlockNumber,
|
| 292 |
+
BlockHash: ethermanBlock1.BlockHash,
|
| 293 |
+
ParentHash: ethermanBlock1.ParentHash,
|
| 294 |
+
ReceivedAt: ethermanBlock1.ReceivedAt,
|
| 295 |
+
Checked: true,
|
| 296 |
}
|
| 297 |
|
| 298 |
executionResponse := executor.ProcessBatchResponseV2{
|
|
|
|
| 304 |
Return(&executionResponse, nil).
|
| 305 |
Times(1)
|
| 306 |
|
| 307 |
+
m.Etherman.
|
| 308 |
+
On("GetFinalizedBlockNumber", ctx).
|
| 309 |
+
Return(ethBlock1.NumberU64(), nil).
|
| 310 |
+
Once()
|
| 311 |
+
|
| 312 |
m.State.
|
| 313 |
On("AddBlock", ctx, stateBlock, m.DbTx).
|
| 314 |
Return(nil).
|
| 315 |
Once()
|
| 316 |
|
| 317 |
fb := []state.ForcedBatch{{
|
| 318 |
+
BlockNumber: lastBlock1.BlockNumber,
|
| 319 |
ForcedBatchNumber: 1,
|
| 320 |
Sequencer: sequencedBatch.Coinbase,
|
| 321 |
GlobalExitRoot: sequencedBatch.PolygonRollupBaseEtrogBatchData.ForcedGlobalExitRoot,
|
|
|
|
| 350 |
BatchNumber: sequencedBatch.BatchNumber,
|
| 351 |
TxHash: sequencedBatch.TxHash,
|
| 352 |
Coinbase: sequencedBatch.Coinbase,
|
| 353 |
+
BlockNumber: ethermanBlock1.BlockNumber,
|
| 354 |
TimestampBatchEtrog: &t,
|
| 355 |
L1InfoRoot: &forcedGER,
|
| 356 |
}
|
|
|
|
| 396 |
// but it used a feature that is not implemented in new one that is asking beyond the last block on L1
|
| 397 |
func TestSequenceForcedBatchIncaberry(t *testing.T) {
|
| 398 |
genesis := state.Genesis{
|
| 399 |
+
RollupBlockNumber: uint64(123456),
|
| 400 |
}
|
| 401 |
cfg := Config{
|
| 402 |
SyncInterval: cfgTypes.Duration{Duration: 1 * time.Second},
|
| 403 |
SyncChunkSize: 10,
|
| 404 |
L1SynchronizationMode: SequentialMode,
|
| 405 |
+
SyncBlockProtection: "latest",
|
| 406 |
}
|
| 407 |
|
| 408 |
m := mocks{
|
|
|
|
| 413 |
ZKEVMClient: mock_syncinterfaces.NewZKEVMClientInterface(t),
|
| 414 |
}
|
| 415 |
ethermanForL1 := []syncinterfaces.EthermanFullInterface{m.Etherman}
|
| 416 |
+
sync, err := NewSynchronizer(true, m.Etherman, ethermanForL1, m.State, m.Pool, m.EthTxManager, m.ZKEVMClient, m.zkEVMClientEthereumCompatible, nil, genesis, cfg, false)
|
| 417 |
require.NoError(t, err)
|
| 418 |
|
| 419 |
// state preparation
|
|
|
|
| 423 |
Run(func(args mock.Arguments) {
|
| 424 |
ctx := args[0].(context.Context)
|
| 425 |
parentHash := common.HexToHash("0x111")
|
| 426 |
+
ethHeader0 := ðTypes.Header{Number: big.NewInt(0), ParentHash: parentHash}
|
| 427 |
+
ethBlock0 := ethTypes.NewBlockWithHeader(ethHeader0)
|
| 428 |
+
ethHeader1 := ðTypes.Header{Number: big.NewInt(1), ParentHash: ethBlock0.Hash()}
|
| 429 |
+
ethBlock1 := ethTypes.NewBlockWithHeader(ethHeader1)
|
| 430 |
+
lastBlock0 := &state.Block{BlockHash: ethBlock0.Hash(), BlockNumber: ethBlock0.Number().Uint64(), ParentHash: ethBlock0.ParentHash()}
|
| 431 |
+
lastBlock1 := &state.Block{BlockHash: ethBlock1.Hash(), BlockNumber: ethBlock1.Number().Uint64(), ParentHash: ethBlock1.ParentHash()}
|
| 432 |
m.State.
|
| 433 |
On("GetForkIDByBatchNumber", mock.Anything).
|
| 434 |
Return(uint64(1), nil).
|
| 435 |
Maybe()
|
|
|
|
|
|
|
|
|
|
|
|
|
| 436 |
|
| 437 |
m.State.
|
| 438 |
On("GetLastBlock", ctx, m.DbTx).
|
| 439 |
+
Return(lastBlock0, nil).
|
| 440 |
Once()
|
| 441 |
|
| 442 |
m.State.
|
|
|
|
| 474 |
Return(nil).
|
| 475 |
Once()
|
| 476 |
|
| 477 |
+
n := big.NewInt(rpc.LatestBlockNumber.Int64())
|
| 478 |
m.Etherman.
|
| 479 |
+
On("HeaderByNumber", ctx, n).
|
| 480 |
+
Return(ethHeader1, nil).
|
| 481 |
Once()
|
| 482 |
|
|
|
|
| 483 |
m.Etherman.
|
| 484 |
+
On("EthBlockByNumber", ctx, lastBlock0.BlockNumber).
|
| 485 |
+
Return(ethBlock0, nil).
|
| 486 |
Once()
|
| 487 |
|
| 488 |
sequencedForceBatch := etherman.SequencedForceBatch{
|
|
|
|
| 498 |
}
|
| 499 |
|
| 500 |
forceb := []etherman.ForcedBatch{{
|
| 501 |
+
BlockNumber: lastBlock1.BlockNumber,
|
| 502 |
ForcedBatchNumber: 1,
|
| 503 |
Sequencer: sequencedForceBatch.Coinbase,
|
| 504 |
GlobalExitRoot: sequencedForceBatch.PolygonRollupBaseEtrogBatchData.ForcedGlobalExitRoot,
|
|
|
|
| 506 |
ForcedAt: time.Unix(int64(sequencedForceBatch.PolygonRollupBaseEtrogBatchData.ForcedTimestamp), 0),
|
| 507 |
}}
|
| 508 |
|
| 509 |
+
ethermanBlock0 := etherman.Block{
|
| 510 |
+
BlockNumber: ethBlock0.NumberU64(),
|
| 511 |
+
BlockHash: ethBlock0.Hash(),
|
| 512 |
+
ParentHash: ethBlock0.ParentHash(),
|
| 513 |
+
}
|
| 514 |
+
ethermanBlock1 := etherman.Block{
|
| 515 |
+
BlockNumber: ethBlock1.NumberU64(),
|
| 516 |
+
BlockHash: ethBlock1.Hash(),
|
| 517 |
+
ParentHash: ethBlock1.ParentHash(),
|
| 518 |
SequencedForceBatches: [][]etherman.SequencedForceBatch{{sequencedForceBatch}},
|
| 519 |
ForcedBatches: forceb,
|
| 520 |
}
|
| 521 |
+
blocks := []etherman.Block{ethermanBlock0, ethermanBlock1}
|
| 522 |
order := map[common.Hash][]etherman.Order{
|
| 523 |
+
ethBlock1.Hash(): {
|
| 524 |
{
|
| 525 |
Name: etherman.ForcedBatchesOrder,
|
| 526 |
Pos: 0,
|
|
|
|
| 532 |
},
|
| 533 |
}
|
| 534 |
|
| 535 |
+
fromBlock := ethBlock0.NumberU64()
|
| 536 |
toBlock := fromBlock + cfg.SyncChunkSize
|
| 537 |
+
if toBlock > ethBlock1.NumberU64() {
|
| 538 |
+
toBlock = ethBlock1.NumberU64()
|
| 539 |
+
}
|
| 540 |
m.Etherman.
|
| 541 |
On("GetRollupInfoByBlockRange", ctx, fromBlock, &toBlock).
|
| 542 |
Return(blocks, order, nil).
|
| 543 |
Once()
|
| 544 |
|
| 545 |
+
m.Etherman.
|
| 546 |
+
On("GetFinalizedBlockNumber", ctx).
|
| 547 |
+
Return(ethBlock1.NumberU64(), nil).
|
| 548 |
+
Once()
|
| 549 |
+
|
| 550 |
m.State.
|
| 551 |
On("BeginStateTransaction", ctx).
|
| 552 |
Return(m.DbTx, nil).
|
| 553 |
Once()
|
| 554 |
|
| 555 |
stateBlock := &state.Block{
|
| 556 |
+
BlockNumber: ethermanBlock1.BlockNumber,
|
| 557 |
+
BlockHash: ethermanBlock1.BlockHash,
|
| 558 |
+
ParentHash: ethermanBlock1.ParentHash,
|
| 559 |
+
ReceivedAt: ethermanBlock1.ReceivedAt,
|
| 560 |
+
Checked: true,
|
| 561 |
}
|
| 562 |
|
| 563 |
m.State.
|
|
|
|
| 565 |
Return(nil).
|
| 566 |
Once()
|
| 567 |
|
| 568 |
+
m.State.
|
| 569 |
+
On("GetForkIDByBlockNumber", stateBlock.BlockNumber).
|
| 570 |
+
Return(uint64(9), nil).
|
| 571 |
+
Once()
|
| 572 |
+
|
| 573 |
fb := []state.ForcedBatch{{
|
| 574 |
+
BlockNumber: lastBlock1.BlockNumber,
|
| 575 |
ForcedBatchNumber: 1,
|
| 576 |
Sequencer: sequencedForceBatch.Coinbase,
|
| 577 |
GlobalExitRoot: sequencedForceBatch.PolygonRollupBaseEtrogBatchData.ForcedGlobalExitRoot,
|
|
|
|
| 603 |
processingContext := state.ProcessingContext{
|
| 604 |
BatchNumber: sequencedForceBatch.BatchNumber,
|
| 605 |
Coinbase: sequencedForceBatch.Coinbase,
|
| 606 |
+
Timestamp: ethBlock1.ReceivedAt,
|
| 607 |
GlobalExitRoot: sequencedForceBatch.PolygonRollupBaseEtrogBatchData.ForcedGlobalExitRoot,
|
| 608 |
ForcedBatchNum: &f,
|
| 609 |
BatchL2Data: &sequencedForceBatch.PolygonRollupBaseEtrogBatchData.Transactions,
|
|
|
|
| 618 |
TxHash: sequencedForceBatch.TxHash,
|
| 619 |
Coinbase: sequencedForceBatch.Coinbase,
|
| 620 |
SequencerAddr: sequencedForceBatch.Coinbase,
|
| 621 |
+
BlockNumber: ethermanBlock1.BlockNumber,
|
| 622 |
}
|
| 623 |
|
| 624 |
m.State.
|
|
|
|
| 642 |
|
| 643 |
m.DbTx.
|
| 644 |
On("Commit", ctx).
|
| 645 |
+
Run(func(args mock.Arguments) {
|
| 646 |
+
sync.Stop()
|
| 647 |
+
ctx.Done()
|
| 648 |
+
}).
|
| 649 |
Return(nil).
|
| 650 |
Once()
|
| 651 |
}).
|
|
|
|
| 658 |
|
| 659 |
func setupGenericTest(t *testing.T) (*state.Genesis, *Config, *mocks) {
|
| 660 |
genesis := state.Genesis{
|
| 661 |
+
RollupBlockNumber: uint64(123456),
|
| 662 |
}
|
| 663 |
cfg := Config{
|
| 664 |
SyncInterval: cfgTypes.Duration{Duration: 1 * time.Second},
|
| 665 |
SyncChunkSize: 10,
|
| 666 |
L1SynchronizationMode: SequentialMode,
|
| 667 |
+
SyncBlockProtection: "latest",
|
| 668 |
L1ParallelSynchronization: L1ParallelSynchronizationConfig{
|
| 669 |
MaxClients: 2,
|
| 670 |
MaxPendingNoProcessedBlocks: 2,
|
|
|
|
| 679 |
}
|
| 680 |
|
| 681 |
m := mocks{
|
| 682 |
+
Etherman: mock_syncinterfaces.NewEthermanFullInterface(t),
|
| 683 |
+
State: mock_syncinterfaces.NewStateFullInterface(t),
|
| 684 |
+
Pool: mock_syncinterfaces.NewPoolInterface(t),
|
| 685 |
+
DbTx: syncMocks.NewDbTxMock(t),
|
| 686 |
+
ZKEVMClient: mock_syncinterfaces.NewZKEVMClientInterface(t),
|
| 687 |
+
zkEVMClientEthereumCompatible: mock_syncinterfaces.NewZKEVMClientEthereumCompatibleInterface(t),
|
| 688 |
+
EthTxManager: mock_syncinterfaces.NewEthTxManager(t),
|
| 689 |
//EventLog: newEventLogMock(t),
|
| 690 |
}
|
| 691 |
return &genesis, &cfg, &m
|
|
|
|
| 919 |
Return(nil).
|
| 920 |
Once()
|
| 921 |
}
|
| 922 |
+
|
| 923 |
+
func TestReorg(t *testing.T) {
|
| 924 |
+
genesis := state.Genesis{
|
| 925 |
+
RollupBlockNumber: uint64(0),
|
| 926 |
+
}
|
| 927 |
+
cfg := Config{
|
| 928 |
+
SyncInterval: cfgTypes.Duration{Duration: 1 * time.Second},
|
| 929 |
+
SyncChunkSize: 3,
|
| 930 |
+
L1SynchronizationMode: SequentialMode,
|
| 931 |
+
SyncBlockProtection: "latest",
|
| 932 |
+
L1BlockCheck: L1BlockCheckConfig{
|
| 933 |
+
Enable: false,
|
| 934 |
+
},
|
| 935 |
+
}
|
| 936 |
+
|
| 937 |
+
m := mocks{
|
| 938 |
+
Etherman: mock_syncinterfaces.NewEthermanFullInterface(t),
|
| 939 |
+
State: mock_syncinterfaces.NewStateFullInterface(t),
|
| 940 |
+
Pool: mock_syncinterfaces.NewPoolInterface(t),
|
| 941 |
+
DbTx: syncMocks.NewDbTxMock(t),
|
| 942 |
+
ZKEVMClient: mock_syncinterfaces.NewZKEVMClientInterface(t),
|
| 943 |
+
EthTxManager: mock_syncinterfaces.NewEthTxManager(t),
|
| 944 |
+
}
|
| 945 |
+
ethermanForL1 := []syncinterfaces.EthermanFullInterface{m.Etherman}
|
| 946 |
+
sync, err := NewSynchronizer(false, m.Etherman, ethermanForL1, m.State, m.Pool, m.EthTxManager, m.ZKEVMClient, m.zkEVMClientEthereumCompatible, nil, genesis, cfg, false)
|
| 947 |
+
require.NoError(t, err)
|
| 948 |
+
|
| 949 |
+
// state preparation
|
| 950 |
+
ctxMatchBy := mock.MatchedBy(func(ctx context.Context) bool { return ctx != nil })
|
| 951 |
+
forkIdInterval := state.ForkIDInterval{
|
| 952 |
+
ForkId: 9,
|
| 953 |
+
FromBatchNumber: 0,
|
| 954 |
+
ToBatchNumber: math.MaxUint64,
|
| 955 |
+
}
|
| 956 |
+
m.State.EXPECT().GetForkIDInMemory(uint64(9)).Return(&forkIdInterval)
|
| 957 |
+
|
| 958 |
+
m.State.
|
| 959 |
+
On("BeginStateTransaction", ctxMatchBy).
|
| 960 |
+
Run(func(args mock.Arguments) {
|
| 961 |
+
ctx := args[0].(context.Context)
|
| 962 |
+
parentHash := common.HexToHash("0x111")
|
| 963 |
+
ethHeader0 := ðTypes.Header{Number: big.NewInt(0), ParentHash: parentHash}
|
| 964 |
+
ethBlock0 := ethTypes.NewBlockWithHeader(ethHeader0)
|
| 965 |
+
ethHeader1bis := ðTypes.Header{Number: big.NewInt(1), ParentHash: ethBlock0.Hash(), Time: 10, GasUsed: 20, Root: common.HexToHash("0x234")}
|
| 966 |
+
ethBlock1bis := ethTypes.NewBlockWithHeader(ethHeader1bis)
|
| 967 |
+
ethHeader2bis := ðTypes.Header{Number: big.NewInt(2), ParentHash: ethBlock1bis.Hash()}
|
| 968 |
+
ethBlock2bis := ethTypes.NewBlockWithHeader(ethHeader2bis)
|
| 969 |
+
ethHeader3bis := ðTypes.Header{Number: big.NewInt(3), ParentHash: ethBlock2bis.Hash()}
|
| 970 |
+
ethBlock3bis := ethTypes.NewBlockWithHeader(ethHeader3bis)
|
| 971 |
+
ethHeader1 := ðTypes.Header{Number: big.NewInt(1), ParentHash: ethBlock0.Hash()}
|
| 972 |
+
ethBlock1 := ethTypes.NewBlockWithHeader(ethHeader1)
|
| 973 |
+
ethHeader2 := ðTypes.Header{Number: big.NewInt(2), ParentHash: ethBlock1.Hash()}
|
| 974 |
+
ethBlock2 := ethTypes.NewBlockWithHeader(ethHeader2)
|
| 975 |
+
ethHeader3 := ðTypes.Header{Number: big.NewInt(3), ParentHash: ethBlock2.Hash()}
|
| 976 |
+
ethBlock3 := ethTypes.NewBlockWithHeader(ethHeader3)
|
| 977 |
+
|
| 978 |
+
lastBlock0 := &state.Block{BlockHash: ethBlock0.Hash(), BlockNumber: ethBlock0.Number().Uint64(), ParentHash: ethBlock0.ParentHash()}
|
| 979 |
+
lastBlock1 := &state.Block{BlockHash: ethBlock1.Hash(), BlockNumber: ethBlock1.Number().Uint64(), ParentHash: ethBlock1.ParentHash()}
|
| 980 |
+
|
| 981 |
+
m.State.
|
| 982 |
+
On("GetForkIDByBatchNumber", mock.Anything).
|
| 983 |
+
Return(uint64(9), nil).
|
| 984 |
+
Maybe()
|
| 985 |
+
m.State.
|
| 986 |
+
On("GetLastBlock", ctx, m.DbTx).
|
| 987 |
+
Return(lastBlock1, nil).
|
| 988 |
+
Once()
|
| 989 |
+
|
| 990 |
+
m.State.
|
| 991 |
+
On("GetLastBatchNumber", ctx, m.DbTx).
|
| 992 |
+
Return(uint64(10), nil).
|
| 993 |
+
Once()
|
| 994 |
+
|
| 995 |
+
m.State.
|
| 996 |
+
On("SetInitSyncBatch", ctx, uint64(10), m.DbTx).
|
| 997 |
+
Return(nil).
|
| 998 |
+
Once()
|
| 999 |
+
|
| 1000 |
+
m.DbTx.
|
| 1001 |
+
On("Commit", ctx).
|
| 1002 |
+
Return(nil).
|
| 1003 |
+
Once()
|
| 1004 |
+
|
| 1005 |
+
m.Etherman.
|
| 1006 |
+
On("GetLatestBatchNumber").
|
| 1007 |
+
Return(uint64(10), nil)
|
| 1008 |
+
|
| 1009 |
+
var nilDbTx pgx.Tx
|
| 1010 |
+
m.State.
|
| 1011 |
+
On("GetLastBatchNumber", ctx, nilDbTx).
|
| 1012 |
+
Return(uint64(10), nil)
|
| 1013 |
+
|
| 1014 |
+
m.Etherman.
|
| 1015 |
+
On("GetLatestVerifiedBatchNum").
|
| 1016 |
+
Return(uint64(10), nil)
|
| 1017 |
+
|
| 1018 |
+
m.State.
|
| 1019 |
+
On("SetLastBatchInfoSeenOnEthereum", ctx, uint64(10), uint64(10), nilDbTx).
|
| 1020 |
+
Return(nil)
|
| 1021 |
+
|
| 1022 |
+
m.Etherman.
|
| 1023 |
+
On("EthBlockByNumber", ctx, lastBlock1.BlockNumber).
|
| 1024 |
+
Return(ethBlock1, nil).
|
| 1025 |
+
Once()
|
| 1026 |
+
|
| 1027 |
+
m.ZKEVMClient.
|
| 1028 |
+
On("BatchNumber", ctx).
|
| 1029 |
+
Return(uint64(1), nil).
|
| 1030 |
+
Once()
|
| 1031 |
+
|
| 1032 |
+
n := big.NewInt(rpc.LatestBlockNumber.Int64())
|
| 1033 |
+
m.Etherman.
|
| 1034 |
+
On("HeaderByNumber", mock.Anything, n).
|
| 1035 |
+
Return(ethHeader3bis, nil).
|
| 1036 |
+
Once()
|
| 1037 |
+
|
| 1038 |
+
m.Etherman.
|
| 1039 |
+
On("EthBlockByNumber", ctx, lastBlock1.BlockNumber).
|
| 1040 |
+
Return(ethBlock1, nil).
|
| 1041 |
+
Once()
|
| 1042 |
+
|
| 1043 |
+
ti := time.Date(2024, 1, 1, 1, 0, 0, 0, time.UTC)
|
| 1044 |
+
|
| 1045 |
+
ethermanBlock1bis := etherman.Block{
|
| 1046 |
+
BlockNumber: 1,
|
| 1047 |
+
ReceivedAt: ti,
|
| 1048 |
+
BlockHash: ethBlock1bis.Hash(),
|
| 1049 |
+
ParentHash: ethBlock1bis.ParentHash(),
|
| 1050 |
+
}
|
| 1051 |
+
ethermanBlock2bis := etherman.Block{
|
| 1052 |
+
BlockNumber: 2,
|
| 1053 |
+
ReceivedAt: ti,
|
| 1054 |
+
BlockHash: ethBlock2bis.Hash(),
|
| 1055 |
+
ParentHash: ethBlock2bis.ParentHash(),
|
| 1056 |
+
}
|
| 1057 |
+
blocks := []etherman.Block{ethermanBlock1bis, ethermanBlock2bis}
|
| 1058 |
+
order := map[common.Hash][]etherman.Order{}
|
| 1059 |
+
|
| 1060 |
+
fromBlock := ethBlock1.NumberU64()
|
| 1061 |
+
toBlock := fromBlock + cfg.SyncChunkSize
|
| 1062 |
+
if toBlock > ethBlock3.NumberU64() {
|
| 1063 |
+
toBlock = ethBlock3.NumberU64()
|
| 1064 |
+
}
|
| 1065 |
+
m.Etherman.
|
| 1066 |
+
On("GetRollupInfoByBlockRange", mock.Anything, fromBlock, &toBlock).
|
| 1067 |
+
Return(blocks, order, nil).
|
| 1068 |
+
Once()
|
| 1069 |
+
|
| 1070 |
+
m.State.
|
| 1071 |
+
On("BeginStateTransaction", ctx).
|
| 1072 |
+
Return(m.DbTx, nil).
|
| 1073 |
+
Once()
|
| 1074 |
+
|
| 1075 |
+
var depth uint64 = 1
|
| 1076 |
+
stateBlock0 := &state.Block{
|
| 1077 |
+
BlockNumber: ethBlock0.NumberU64(),
|
| 1078 |
+
BlockHash: ethBlock0.Hash(),
|
| 1079 |
+
ParentHash: ethBlock0.ParentHash(),
|
| 1080 |
+
ReceivedAt: ti,
|
| 1081 |
+
}
|
| 1082 |
+
m.State.
|
| 1083 |
+
On("GetPreviousBlock", ctx, depth, m.DbTx).
|
| 1084 |
+
Return(stateBlock0, nil).
|
| 1085 |
+
Once()
|
| 1086 |
+
|
| 1087 |
+
m.DbTx.
|
| 1088 |
+
On("Commit", ctx).
|
| 1089 |
+
Return(nil).
|
| 1090 |
+
Once()
|
| 1091 |
+
|
| 1092 |
+
m.Etherman.
|
| 1093 |
+
On("EthBlockByNumber", ctx, lastBlock0.BlockNumber).
|
| 1094 |
+
Return(ethBlock0, nil).
|
| 1095 |
+
Once()
|
| 1096 |
+
|
| 1097 |
+
m.State.
|
| 1098 |
+
On("BeginStateTransaction", ctx).
|
| 1099 |
+
Return(m.DbTx, nil).
|
| 1100 |
+
Once()
|
| 1101 |
+
|
| 1102 |
+
m.State.
|
| 1103 |
+
On("Reset", ctx, ethBlock0.NumberU64(), m.DbTx).
|
| 1104 |
+
Return(nil).
|
| 1105 |
+
Once()
|
| 1106 |
+
|
| 1107 |
+
m.EthTxManager.
|
| 1108 |
+
On("Reorg", ctx, ethBlock0.NumberU64()+1, m.DbTx).
|
| 1109 |
+
Return(nil).
|
| 1110 |
+
Once()
|
| 1111 |
+
|
| 1112 |
+
m.DbTx.
|
| 1113 |
+
On("Commit", ctx).
|
| 1114 |
+
Return(nil).
|
| 1115 |
+
Once()
|
| 1116 |
+
|
| 1117 |
+
m.Etherman.
|
| 1118 |
+
On("EthBlockByNumber", ctx, lastBlock0.BlockNumber).
|
| 1119 |
+
Return(ethBlock0, nil).
|
| 1120 |
+
Once()
|
| 1121 |
+
|
| 1122 |
+
m.ZKEVMClient.
|
| 1123 |
+
On("BatchNumber", ctx).
|
| 1124 |
+
Return(uint64(1), nil).
|
| 1125 |
+
Once()
|
| 1126 |
+
|
| 1127 |
+
m.Etherman.
|
| 1128 |
+
On("HeaderByNumber", mock.Anything, n).
|
| 1129 |
+
Return(ethHeader3bis, nil).
|
| 1130 |
+
Once()
|
| 1131 |
+
|
| 1132 |
+
m.Etherman.
|
| 1133 |
+
On("EthBlockByNumber", ctx, lastBlock0.BlockNumber).
|
| 1134 |
+
Return(ethBlock0, nil).
|
| 1135 |
+
Once()
|
| 1136 |
+
|
| 1137 |
+
ethermanBlock0 := etherman.Block{
|
| 1138 |
+
BlockNumber: 0,
|
| 1139 |
+
ReceivedAt: ti,
|
| 1140 |
+
BlockHash: ethBlock0.Hash(),
|
| 1141 |
+
ParentHash: ethBlock0.ParentHash(),
|
| 1142 |
+
}
|
| 1143 |
+
ethermanBlock3bis := etherman.Block{
|
| 1144 |
+
BlockNumber: 3,
|
| 1145 |
+
ReceivedAt: ti,
|
| 1146 |
+
BlockHash: ethBlock3bis.Hash(),
|
| 1147 |
+
ParentHash: ethBlock3bis.ParentHash(),
|
| 1148 |
+
}
|
| 1149 |
+
fromBlock = 0
|
| 1150 |
+
blocks2 := []etherman.Block{ethermanBlock0, ethermanBlock1bis, ethermanBlock2bis, ethermanBlock3bis}
|
| 1151 |
+
m.Etherman.
|
| 1152 |
+
On("GetRollupInfoByBlockRange", mock.Anything, fromBlock, &toBlock).
|
| 1153 |
+
Return(blocks2, order, nil).
|
| 1154 |
+
Once()
|
| 1155 |
+
|
| 1156 |
+
m.Etherman.
|
| 1157 |
+
On("GetFinalizedBlockNumber", ctx).
|
| 1158 |
+
Return(ethBlock2bis.NumberU64(), nil).
|
| 1159 |
+
Once()
|
| 1160 |
+
|
| 1161 |
+
m.State.
|
| 1162 |
+
On("BeginStateTransaction", ctx).
|
| 1163 |
+
Return(m.DbTx, nil).
|
| 1164 |
+
Once()
|
| 1165 |
+
|
| 1166 |
+
stateBlock1bis := &state.Block{
|
| 1167 |
+
BlockNumber: ethermanBlock1bis.BlockNumber,
|
| 1168 |
+
BlockHash: ethermanBlock1bis.BlockHash,
|
| 1169 |
+
ParentHash: ethermanBlock1bis.ParentHash,
|
| 1170 |
+
ReceivedAt: ethermanBlock1bis.ReceivedAt,
|
| 1171 |
+
Checked: true,
|
| 1172 |
+
}
|
| 1173 |
+
m.State.
|
| 1174 |
+
On("AddBlock", ctx, stateBlock1bis, m.DbTx).
|
| 1175 |
+
Return(nil).
|
| 1176 |
+
Once()
|
| 1177 |
+
|
| 1178 |
+
m.State.
|
| 1179 |
+
On("GetStoredFlushID", ctx).
|
| 1180 |
+
Return(uint64(1), cProverIDExecution, nil).
|
| 1181 |
+
Once()
|
| 1182 |
+
|
| 1183 |
+
m.DbTx.
|
| 1184 |
+
On("Commit", ctx).
|
| 1185 |
+
Return(nil).
|
| 1186 |
+
Once()
|
| 1187 |
+
|
| 1188 |
+
m.State.
|
| 1189 |
+
On("BeginStateTransaction", ctx).
|
| 1190 |
+
Return(m.DbTx, nil).
|
| 1191 |
+
Once()
|
| 1192 |
+
|
| 1193 |
+
stateBlock2bis := &state.Block{
|
| 1194 |
+
BlockNumber: ethermanBlock2bis.BlockNumber,
|
| 1195 |
+
BlockHash: ethermanBlock2bis.BlockHash,
|
| 1196 |
+
ParentHash: ethermanBlock2bis.ParentHash,
|
| 1197 |
+
ReceivedAt: ethermanBlock2bis.ReceivedAt,
|
| 1198 |
+
Checked: true,
|
| 1199 |
+
}
|
| 1200 |
+
m.State.
|
| 1201 |
+
On("AddBlock", ctx, stateBlock2bis, m.DbTx).
|
| 1202 |
+
Return(nil).
|
| 1203 |
+
Once()
|
| 1204 |
+
|
| 1205 |
+
m.DbTx.
|
| 1206 |
+
On("Commit", ctx).
|
| 1207 |
+
Return(nil).
|
| 1208 |
+
Once()
|
| 1209 |
+
|
| 1210 |
+
m.State.
|
| 1211 |
+
On("BeginStateTransaction", ctx).
|
| 1212 |
+
Return(m.DbTx, nil).
|
| 1213 |
+
Once()
|
| 1214 |
+
|
| 1215 |
+
stateBlock3bis := &state.Block{
|
| 1216 |
+
BlockNumber: ethermanBlock3bis.BlockNumber,
|
| 1217 |
+
BlockHash: ethermanBlock3bis.BlockHash,
|
| 1218 |
+
ParentHash: ethermanBlock3bis.ParentHash,
|
| 1219 |
+
ReceivedAt: ethermanBlock3bis.ReceivedAt,
|
| 1220 |
+
Checked: false,
|
| 1221 |
+
}
|
| 1222 |
+
m.State.
|
| 1223 |
+
On("AddBlock", ctx, stateBlock3bis, m.DbTx).
|
| 1224 |
+
Return(nil).
|
| 1225 |
+
Once()
|
| 1226 |
+
|
| 1227 |
+
m.DbTx.
|
| 1228 |
+
On("Commit", ctx).
|
| 1229 |
+
Return(nil).
|
| 1230 |
+
Run(func(args mock.Arguments) {
|
| 1231 |
+
sync.Stop()
|
| 1232 |
+
ctx.Done()
|
| 1233 |
+
}).
|
| 1234 |
+
Once()
|
| 1235 |
+
}).
|
| 1236 |
+
Return(m.DbTx, nil).
|
| 1237 |
+
Once()
|
| 1238 |
+
|
| 1239 |
+
err = sync.Sync()
|
| 1240 |
+
require.NoError(t, err)
|
| 1241 |
+
}
|
| 1242 |
+
|
| 1243 |
+
func TestLatestSyncedBlockEmpty(t *testing.T) {
|
| 1244 |
+
genesis := state.Genesis{
|
| 1245 |
+
RollupBlockNumber: uint64(0),
|
| 1246 |
+
}
|
| 1247 |
+
cfg := Config{
|
| 1248 |
+
SyncInterval: cfgTypes.Duration{Duration: 1 * time.Second},
|
| 1249 |
+
SyncChunkSize: 3,
|
| 1250 |
+
L1SynchronizationMode: SequentialMode,
|
| 1251 |
+
SyncBlockProtection: "latest",
|
| 1252 |
+
L1BlockCheck: L1BlockCheckConfig{
|
| 1253 |
+
Enable: false,
|
| 1254 |
+
},
|
| 1255 |
+
}
|
| 1256 |
+
|
| 1257 |
+
m := mocks{
|
| 1258 |
+
Etherman: mock_syncinterfaces.NewEthermanFullInterface(t),
|
| 1259 |
+
State: mock_syncinterfaces.NewStateFullInterface(t),
|
| 1260 |
+
Pool: mock_syncinterfaces.NewPoolInterface(t),
|
| 1261 |
+
DbTx: syncMocks.NewDbTxMock(t),
|
| 1262 |
+
ZKEVMClient: mock_syncinterfaces.NewZKEVMClientInterface(t),
|
| 1263 |
+
EthTxManager: mock_syncinterfaces.NewEthTxManager(t),
|
| 1264 |
+
}
|
| 1265 |
+
ethermanForL1 := []syncinterfaces.EthermanFullInterface{m.Etherman}
|
| 1266 |
+
sync, err := NewSynchronizer(false, m.Etherman, ethermanForL1, m.State, m.Pool, m.EthTxManager, m.ZKEVMClient, m.zkEVMClientEthereumCompatible, nil, genesis, cfg, false)
|
| 1267 |
+
require.NoError(t, err)
|
| 1268 |
+
|
| 1269 |
+
// state preparation
|
| 1270 |
+
ctxMatchBy := mock.MatchedBy(func(ctx context.Context) bool { return ctx != nil })
|
| 1271 |
+
forkIdInterval := state.ForkIDInterval{
|
| 1272 |
+
ForkId: 9,
|
| 1273 |
+
FromBatchNumber: 0,
|
| 1274 |
+
ToBatchNumber: math.MaxUint64,
|
| 1275 |
+
}
|
| 1276 |
+
m.State.EXPECT().GetForkIDInMemory(uint64(9)).Return(&forkIdInterval)
|
| 1277 |
+
|
| 1278 |
+
m.State.
|
| 1279 |
+
On("BeginStateTransaction", ctxMatchBy).
|
| 1280 |
+
Run(func(args mock.Arguments) {
|
| 1281 |
+
ctx := args[0].(context.Context)
|
| 1282 |
+
parentHash := common.HexToHash("0x111")
|
| 1283 |
+
ethHeader0 := ðTypes.Header{Number: big.NewInt(0), ParentHash: parentHash}
|
| 1284 |
+
ethBlock0 := ethTypes.NewBlockWithHeader(ethHeader0)
|
| 1285 |
+
ethHeader1 := ðTypes.Header{Number: big.NewInt(1), ParentHash: ethBlock0.Hash()}
|
| 1286 |
+
ethBlock1 := ethTypes.NewBlockWithHeader(ethHeader1)
|
| 1287 |
+
ethHeader2 := ðTypes.Header{Number: big.NewInt(2), ParentHash: ethBlock1.Hash()}
|
| 1288 |
+
ethBlock2 := ethTypes.NewBlockWithHeader(ethHeader2)
|
| 1289 |
+
ethHeader3 := ðTypes.Header{Number: big.NewInt(3), ParentHash: ethBlock2.Hash()}
|
| 1290 |
+
ethBlock3 := ethTypes.NewBlockWithHeader(ethHeader3)
|
| 1291 |
+
|
| 1292 |
+
lastBlock0 := &state.Block{BlockHash: ethBlock0.Hash(), BlockNumber: ethBlock0.Number().Uint64(), ParentHash: ethBlock0.ParentHash()}
|
| 1293 |
+
lastBlock1 := &state.Block{BlockHash: ethBlock1.Hash(), BlockNumber: ethBlock1.Number().Uint64(), ParentHash: ethBlock1.ParentHash()}
|
| 1294 |
+
|
| 1295 |
+
m.State.
|
| 1296 |
+
On("GetForkIDByBatchNumber", mock.Anything).
|
| 1297 |
+
Return(uint64(9), nil).
|
| 1298 |
+
Maybe()
|
| 1299 |
+
m.State.
|
| 1300 |
+
On("GetLastBlock", ctx, m.DbTx).
|
| 1301 |
+
Return(lastBlock1, nil).
|
| 1302 |
+
Once()
|
| 1303 |
+
|
| 1304 |
+
m.State.
|
| 1305 |
+
On("GetLastBatchNumber", ctx, m.DbTx).
|
| 1306 |
+
Return(uint64(10), nil).
|
| 1307 |
+
Once()
|
| 1308 |
+
|
| 1309 |
+
m.State.
|
| 1310 |
+
On("SetInitSyncBatch", ctx, uint64(10), m.DbTx).
|
| 1311 |
+
Return(nil).
|
| 1312 |
+
Once()
|
| 1313 |
+
|
| 1314 |
+
m.DbTx.
|
| 1315 |
+
On("Commit", ctx).
|
| 1316 |
+
Return(nil).
|
| 1317 |
+
Once()
|
| 1318 |
+
|
| 1319 |
+
m.Etherman.
|
| 1320 |
+
On("GetLatestBatchNumber").
|
| 1321 |
+
Return(uint64(10), nil)
|
| 1322 |
+
|
| 1323 |
+
var nilDbTx pgx.Tx
|
| 1324 |
+
m.State.
|
| 1325 |
+
On("GetLastBatchNumber", ctx, nilDbTx).
|
| 1326 |
+
Return(uint64(10), nil)
|
| 1327 |
+
|
| 1328 |
+
m.Etherman.
|
| 1329 |
+
On("GetLatestVerifiedBatchNum").
|
| 1330 |
+
Return(uint64(10), nil)
|
| 1331 |
+
|
| 1332 |
+
m.State.
|
| 1333 |
+
On("SetLastBatchInfoSeenOnEthereum", ctx, uint64(10), uint64(10), nilDbTx).
|
| 1334 |
+
Return(nil)
|
| 1335 |
+
|
| 1336 |
+
m.Etherman.
|
| 1337 |
+
On("EthBlockByNumber", ctx, lastBlock1.BlockNumber).
|
| 1338 |
+
Return(ethBlock1, nil).
|
| 1339 |
+
Once()
|
| 1340 |
+
|
| 1341 |
+
m.ZKEVMClient.
|
| 1342 |
+
On("BatchNumber", ctx).
|
| 1343 |
+
Return(uint64(1), nil).
|
| 1344 |
+
Once()
|
| 1345 |
+
|
| 1346 |
+
n := big.NewInt(rpc.LatestBlockNumber.Int64())
|
| 1347 |
+
m.Etherman.
|
| 1348 |
+
On("HeaderByNumber", mock.Anything, n).
|
| 1349 |
+
Return(ethHeader3, nil).
|
| 1350 |
+
Once()
|
| 1351 |
+
|
| 1352 |
+
m.Etherman.
|
| 1353 |
+
On("EthBlockByNumber", ctx, lastBlock1.BlockNumber).
|
| 1354 |
+
Return(ethBlock1, nil).
|
| 1355 |
+
Once()
|
| 1356 |
+
|
| 1357 |
+
blocks := []etherman.Block{}
|
| 1358 |
+
order := map[common.Hash][]etherman.Order{}
|
| 1359 |
+
|
| 1360 |
+
fromBlock := ethBlock1.NumberU64()
|
| 1361 |
+
toBlock := fromBlock + cfg.SyncChunkSize
|
| 1362 |
+
if toBlock > ethBlock3.NumberU64() {
|
| 1363 |
+
toBlock = ethBlock3.NumberU64()
|
| 1364 |
+
}
|
| 1365 |
+
m.Etherman.
|
| 1366 |
+
On("GetRollupInfoByBlockRange", mock.Anything, fromBlock, &toBlock).
|
| 1367 |
+
Return(blocks, order, nil).
|
| 1368 |
+
Once()
|
| 1369 |
+
|
| 1370 |
+
ti := time.Date(2024, 1, 1, 1, 0, 0, 0, time.UTC)
|
| 1371 |
+
var depth uint64 = 1
|
| 1372 |
+
stateBlock0 := &state.Block{
|
| 1373 |
+
BlockNumber: ethBlock0.NumberU64(),
|
| 1374 |
+
BlockHash: ethBlock0.Hash(),
|
| 1375 |
+
ParentHash: ethBlock0.ParentHash(),
|
| 1376 |
+
ReceivedAt: ti,
|
| 1377 |
+
}
|
| 1378 |
+
m.State.
|
| 1379 |
+
On("GetPreviousBlock", ctx, depth, nil).
|
| 1380 |
+
Return(stateBlock0, nil).
|
| 1381 |
+
Once()
|
| 1382 |
+
|
| 1383 |
+
m.Etherman.
|
| 1384 |
+
On("EthBlockByNumber", ctx, lastBlock0.BlockNumber).
|
| 1385 |
+
Return(ethBlock0, nil).
|
| 1386 |
+
Once()
|
| 1387 |
+
|
| 1388 |
+
m.State.
|
| 1389 |
+
On("BeginStateTransaction", ctx).
|
| 1390 |
+
Return(m.DbTx, nil).
|
| 1391 |
+
Once()
|
| 1392 |
+
|
| 1393 |
+
m.State.
|
| 1394 |
+
On("Reset", ctx, ethBlock0.NumberU64(), m.DbTx).
|
| 1395 |
+
Return(nil).
|
| 1396 |
+
Once()
|
| 1397 |
+
|
| 1398 |
+
m.EthTxManager.
|
| 1399 |
+
On("Reorg", ctx, ethBlock0.NumberU64()+1, m.DbTx).
|
| 1400 |
+
Return(nil).
|
| 1401 |
+
Once()
|
| 1402 |
+
|
| 1403 |
+
m.DbTx.
|
| 1404 |
+
On("Commit", ctx).
|
| 1405 |
+
Return(nil).
|
| 1406 |
+
Once()
|
| 1407 |
+
|
| 1408 |
+
m.Etherman.
|
| 1409 |
+
On("EthBlockByNumber", ctx, lastBlock0.BlockNumber).
|
| 1410 |
+
Return(ethBlock0, nil).
|
| 1411 |
+
Once()
|
| 1412 |
+
|
| 1413 |
+
m.ZKEVMClient.
|
| 1414 |
+
On("BatchNumber", ctx).
|
| 1415 |
+
Return(uint64(1), nil).
|
| 1416 |
+
Once()
|
| 1417 |
+
|
| 1418 |
+
m.Etherman.
|
| 1419 |
+
On("HeaderByNumber", mock.Anything, n).
|
| 1420 |
+
Return(ethHeader3, nil).
|
| 1421 |
+
Once()
|
| 1422 |
+
|
| 1423 |
+
m.Etherman.
|
| 1424 |
+
On("EthBlockByNumber", ctx, lastBlock0.BlockNumber).
|
| 1425 |
+
Return(ethBlock0, nil).
|
| 1426 |
+
Once()
|
| 1427 |
+
|
| 1428 |
+
ethermanBlock0 := etherman.Block{
|
| 1429 |
+
BlockNumber: 0,
|
| 1430 |
+
ReceivedAt: ti,
|
| 1431 |
+
BlockHash: ethBlock0.Hash(),
|
| 1432 |
+
ParentHash: ethBlock0.ParentHash(),
|
| 1433 |
+
}
|
| 1434 |
+
blocks = []etherman.Block{ethermanBlock0}
|
| 1435 |
+
fromBlock = 0
|
| 1436 |
+
m.Etherman.
|
| 1437 |
+
On("GetRollupInfoByBlockRange", mock.Anything, fromBlock, &toBlock).
|
| 1438 |
+
Return(blocks, order, nil).
|
| 1439 |
+
Once()
|
| 1440 |
+
|
| 1441 |
+
m.Etherman.
|
| 1442 |
+
On("GetFinalizedBlockNumber", ctx).
|
| 1443 |
+
Return(ethBlock3.NumberU64(), nil).
|
| 1444 |
+
Run(func(args mock.Arguments) {
|
| 1445 |
+
sync.Stop()
|
| 1446 |
+
ctx.Done()
|
| 1447 |
+
}).
|
| 1448 |
+
Once()
|
| 1449 |
+
}).
|
| 1450 |
+
Return(m.DbTx, nil).
|
| 1451 |
+
Once()
|
| 1452 |
+
|
| 1453 |
+
err = sync.Sync()
|
| 1454 |
+
require.NoError(t, err)
|
| 1455 |
+
}
|
| 1456 |
+
|
| 1457 |
+
func TestRegularReorg(t *testing.T) {
|
| 1458 |
+
genesis := state.Genesis{
|
| 1459 |
+
RollupBlockNumber: uint64(0),
|
| 1460 |
+
}
|
| 1461 |
+
cfg := Config{
|
| 1462 |
+
SyncInterval: cfgTypes.Duration{Duration: 1 * time.Second},
|
| 1463 |
+
SyncChunkSize: 3,
|
| 1464 |
+
L1SynchronizationMode: SequentialMode,
|
| 1465 |
+
SyncBlockProtection: "latest",
|
| 1466 |
+
L1BlockCheck: L1BlockCheckConfig{
|
| 1467 |
+
Enable: false,
|
| 1468 |
+
},
|
| 1469 |
+
}
|
| 1470 |
+
|
| 1471 |
+
m := mocks{
|
| 1472 |
+
Etherman: mock_syncinterfaces.NewEthermanFullInterface(t),
|
| 1473 |
+
State: mock_syncinterfaces.NewStateFullInterface(t),
|
| 1474 |
+
Pool: mock_syncinterfaces.NewPoolInterface(t),
|
| 1475 |
+
DbTx: syncMocks.NewDbTxMock(t),
|
| 1476 |
+
ZKEVMClient: mock_syncinterfaces.NewZKEVMClientInterface(t),
|
| 1477 |
+
EthTxManager: mock_syncinterfaces.NewEthTxManager(t),
|
| 1478 |
+
}
|
| 1479 |
+
ethermanForL1 := []syncinterfaces.EthermanFullInterface{m.Etherman}
|
| 1480 |
+
sync, err := NewSynchronizer(false, m.Etherman, ethermanForL1, m.State, m.Pool, m.EthTxManager, m.ZKEVMClient, m.zkEVMClientEthereumCompatible, nil, genesis, cfg, false)
|
| 1481 |
+
require.NoError(t, err)
|
| 1482 |
+
|
| 1483 |
+
// state preparation
|
| 1484 |
+
ctxMatchBy := mock.MatchedBy(func(ctx context.Context) bool { return ctx != nil })
|
| 1485 |
+
forkIdInterval := state.ForkIDInterval{
|
| 1486 |
+
ForkId: 9,
|
| 1487 |
+
FromBatchNumber: 0,
|
| 1488 |
+
ToBatchNumber: math.MaxUint64,
|
| 1489 |
+
}
|
| 1490 |
+
m.State.EXPECT().GetForkIDInMemory(uint64(9)).Return(&forkIdInterval)
|
| 1491 |
+
|
| 1492 |
+
m.State.
|
| 1493 |
+
On("BeginStateTransaction", ctxMatchBy).
|
| 1494 |
+
Run(func(args mock.Arguments) {
|
| 1495 |
+
ctx := args[0].(context.Context)
|
| 1496 |
+
parentHash := common.HexToHash("0x111")
|
| 1497 |
+
ethHeader0 := ðTypes.Header{Number: big.NewInt(0), ParentHash: parentHash}
|
| 1498 |
+
ethBlock0 := ethTypes.NewBlockWithHeader(ethHeader0)
|
| 1499 |
+
ethHeader1bis := ðTypes.Header{Number: big.NewInt(1), ParentHash: ethBlock0.Hash(), Time: 10, GasUsed: 20, Root: common.HexToHash("0x234")}
|
| 1500 |
+
ethBlock1bis := ethTypes.NewBlockWithHeader(ethHeader1bis)
|
| 1501 |
+
ethHeader2bis := ðTypes.Header{Number: big.NewInt(2), ParentHash: ethBlock1bis.Hash()}
|
| 1502 |
+
ethBlock2bis := ethTypes.NewBlockWithHeader(ethHeader2bis)
|
| 1503 |
+
ethHeader1 := ðTypes.Header{Number: big.NewInt(1), ParentHash: ethBlock0.Hash()}
|
| 1504 |
+
ethBlock1 := ethTypes.NewBlockWithHeader(ethHeader1)
|
| 1505 |
+
ethHeader2 := ðTypes.Header{Number: big.NewInt(2), ParentHash: ethBlock1.Hash()}
|
| 1506 |
+
ethBlock2 := ethTypes.NewBlockWithHeader(ethHeader2)
|
| 1507 |
+
|
| 1508 |
+
lastBlock0 := &state.Block{BlockHash: ethBlock0.Hash(), BlockNumber: ethBlock0.Number().Uint64(), ParentHash: ethBlock0.ParentHash()}
|
| 1509 |
+
lastBlock1 := &state.Block{BlockHash: ethBlock1.Hash(), BlockNumber: ethBlock1.Number().Uint64(), ParentHash: ethBlock1.ParentHash()}
|
| 1510 |
+
|
| 1511 |
+
m.State.
|
| 1512 |
+
On("GetForkIDByBatchNumber", mock.Anything).
|
| 1513 |
+
Return(uint64(9), nil).
|
| 1514 |
+
Maybe()
|
| 1515 |
+
m.State.
|
| 1516 |
+
On("GetLastBlock", ctx, m.DbTx).
|
| 1517 |
+
Return(lastBlock1, nil).
|
| 1518 |
+
Once()
|
| 1519 |
+
|
| 1520 |
+
// After a ResetState get lastblock that must be block 0
|
| 1521 |
+
m.State.
|
| 1522 |
+
On("GetLastBlock", ctx, nil).
|
| 1523 |
+
Return(lastBlock0, nil).
|
| 1524 |
+
Once()
|
| 1525 |
+
|
| 1526 |
+
m.State.
|
| 1527 |
+
On("GetLastBatchNumber", ctx, m.DbTx).
|
| 1528 |
+
Return(uint64(10), nil).
|
| 1529 |
+
Once()
|
| 1530 |
+
|
| 1531 |
+
m.State.
|
| 1532 |
+
On("SetInitSyncBatch", ctx, uint64(10), m.DbTx).
|
| 1533 |
+
Return(nil).
|
| 1534 |
+
Once()
|
| 1535 |
+
|
| 1536 |
+
m.DbTx.
|
| 1537 |
+
On("Commit", ctx).
|
| 1538 |
+
Return(nil).
|
| 1539 |
+
Once()
|
| 1540 |
+
|
| 1541 |
+
m.Etherman.
|
| 1542 |
+
On("GetLatestBatchNumber").
|
| 1543 |
+
Return(uint64(10), nil)
|
| 1544 |
+
|
| 1545 |
+
var nilDbTx pgx.Tx
|
| 1546 |
+
m.State.
|
| 1547 |
+
On("GetLastBatchNumber", ctx, nilDbTx).
|
| 1548 |
+
Return(uint64(10), nil)
|
| 1549 |
+
|
| 1550 |
+
m.Etherman.
|
| 1551 |
+
On("GetLatestVerifiedBatchNum").
|
| 1552 |
+
Return(uint64(10), nil)
|
| 1553 |
+
|
| 1554 |
+
m.State.
|
| 1555 |
+
On("SetLastBatchInfoSeenOnEthereum", ctx, uint64(10), uint64(10), nilDbTx).
|
| 1556 |
+
Return(nil)
|
| 1557 |
+
|
| 1558 |
+
m.Etherman.
|
| 1559 |
+
On("EthBlockByNumber", ctx, lastBlock1.BlockNumber).
|
| 1560 |
+
Return(ethBlock1, nil).
|
| 1561 |
+
Once()
|
| 1562 |
+
|
| 1563 |
+
m.ZKEVMClient.
|
| 1564 |
+
On("BatchNumber", ctx).
|
| 1565 |
+
Return(uint64(1), nil).
|
| 1566 |
+
Once()
|
| 1567 |
+
|
| 1568 |
+
n := big.NewInt(rpc.LatestBlockNumber.Int64())
|
| 1569 |
+
|
| 1570 |
+
m.Etherman.
|
| 1571 |
+
On("EthBlockByNumber", ctx, lastBlock1.BlockNumber).
|
| 1572 |
+
Return(ethBlock1bis, nil).
|
| 1573 |
+
Once()
|
| 1574 |
+
|
| 1575 |
+
m.State.
|
| 1576 |
+
On("BeginStateTransaction", ctx).
|
| 1577 |
+
Return(m.DbTx, nil).
|
| 1578 |
+
Once()
|
| 1579 |
+
|
| 1580 |
+
ti := time.Date(2024, 1, 1, 1, 0, 0, 0, time.UTC)
|
| 1581 |
+
var depth uint64 = 1
|
| 1582 |
+
stateBlock0 := &state.Block{
|
| 1583 |
+
BlockNumber: ethBlock0.NumberU64(),
|
| 1584 |
+
BlockHash: ethBlock0.Hash(),
|
| 1585 |
+
ParentHash: ethBlock0.ParentHash(),
|
| 1586 |
+
ReceivedAt: ti,
|
| 1587 |
+
}
|
| 1588 |
+
m.State.
|
| 1589 |
+
On("GetPreviousBlock", ctx, depth, m.DbTx).
|
| 1590 |
+
Return(stateBlock0, nil).
|
| 1591 |
+
Once()
|
| 1592 |
+
|
| 1593 |
+
m.DbTx.
|
| 1594 |
+
On("Commit", ctx).
|
| 1595 |
+
Return(nil).
|
| 1596 |
+
Once()
|
| 1597 |
+
|
| 1598 |
+
m.Etherman.
|
| 1599 |
+
On("EthBlockByNumber", ctx, lastBlock0.BlockNumber).
|
| 1600 |
+
Return(ethBlock0, nil).
|
| 1601 |
+
Once()
|
| 1602 |
+
|
| 1603 |
+
m.State.
|
| 1604 |
+
On("BeginStateTransaction", ctx).
|
| 1605 |
+
Return(m.DbTx, nil).
|
| 1606 |
+
Once()
|
| 1607 |
+
|
| 1608 |
+
m.State.
|
| 1609 |
+
On("Reset", ctx, ethBlock0.NumberU64(), m.DbTx).
|
| 1610 |
+
Return(nil).
|
| 1611 |
+
Once()
|
| 1612 |
+
|
| 1613 |
+
m.EthTxManager.
|
| 1614 |
+
On("Reorg", ctx, ethBlock0.NumberU64()+1, m.DbTx).
|
| 1615 |
+
Return(nil).
|
| 1616 |
+
Once()
|
| 1617 |
+
|
| 1618 |
+
m.DbTx.
|
| 1619 |
+
On("Commit", ctx).
|
| 1620 |
+
Return(nil).
|
| 1621 |
+
Once()
|
| 1622 |
+
|
| 1623 |
+
m.Etherman.
|
| 1624 |
+
On("EthBlockByNumber", ctx, lastBlock0.BlockNumber).
|
| 1625 |
+
Return(ethBlock0, nil).
|
| 1626 |
+
Once()
|
| 1627 |
+
|
| 1628 |
+
m.ZKEVMClient.
|
| 1629 |
+
On("BatchNumber", ctx).
|
| 1630 |
+
Return(uint64(1), nil).
|
| 1631 |
+
Once()
|
| 1632 |
+
|
| 1633 |
+
m.Etherman.
|
| 1634 |
+
On("HeaderByNumber", mock.Anything, n).
|
| 1635 |
+
Return(ethHeader2bis, nil).
|
| 1636 |
+
Once()
|
| 1637 |
+
|
| 1638 |
+
m.Etherman.
|
| 1639 |
+
On("EthBlockByNumber", ctx, lastBlock0.BlockNumber).
|
| 1640 |
+
Return(ethBlock0, nil).
|
| 1641 |
+
Once()
|
| 1642 |
+
|
| 1643 |
+
ethermanBlock0 := etherman.Block{
|
| 1644 |
+
BlockNumber: 0,
|
| 1645 |
+
ReceivedAt: ti,
|
| 1646 |
+
BlockHash: ethBlock0.Hash(),
|
| 1647 |
+
ParentHash: ethBlock0.ParentHash(),
|
| 1648 |
+
}
|
| 1649 |
+
ethermanBlock1bis := etherman.Block{
|
| 1650 |
+
BlockNumber: 1,
|
| 1651 |
+
ReceivedAt: ti,
|
| 1652 |
+
BlockHash: ethBlock1bis.Hash(),
|
| 1653 |
+
ParentHash: ethBlock1bis.ParentHash(),
|
| 1654 |
+
}
|
| 1655 |
+
ethermanBlock2bis := etherman.Block{
|
| 1656 |
+
BlockNumber: 2,
|
| 1657 |
+
ReceivedAt: ti,
|
| 1658 |
+
BlockHash: ethBlock2bis.Hash(),
|
| 1659 |
+
ParentHash: ethBlock2bis.ParentHash(),
|
| 1660 |
+
}
|
| 1661 |
+
blocks := []etherman.Block{ethermanBlock0, ethermanBlock1bis, ethermanBlock2bis}
|
| 1662 |
+
order := map[common.Hash][]etherman.Order{}
|
| 1663 |
+
|
| 1664 |
+
fromBlock := ethBlock0.NumberU64()
|
| 1665 |
+
toBlock := fromBlock + cfg.SyncChunkSize
|
| 1666 |
+
if toBlock > ethBlock2.NumberU64() {
|
| 1667 |
+
toBlock = ethBlock2.NumberU64()
|
| 1668 |
+
}
|
| 1669 |
+
m.Etherman.
|
| 1670 |
+
On("GetRollupInfoByBlockRange", mock.Anything, fromBlock, &toBlock).
|
| 1671 |
+
Return(blocks, order, nil).
|
| 1672 |
+
Once()
|
| 1673 |
+
|
| 1674 |
+
m.Etherman.
|
| 1675 |
+
On("GetFinalizedBlockNumber", ctx).
|
| 1676 |
+
Return(ethBlock2bis.NumberU64(), nil).
|
| 1677 |
+
Once()
|
| 1678 |
+
|
| 1679 |
+
m.State.
|
| 1680 |
+
On("BeginStateTransaction", ctx).
|
| 1681 |
+
Return(m.DbTx, nil).
|
| 1682 |
+
Once()
|
| 1683 |
+
|
| 1684 |
+
stateBlock1bis := &state.Block{
|
| 1685 |
+
BlockNumber: ethermanBlock1bis.BlockNumber,
|
| 1686 |
+
BlockHash: ethermanBlock1bis.BlockHash,
|
| 1687 |
+
ParentHash: ethermanBlock1bis.ParentHash,
|
| 1688 |
+
ReceivedAt: ethermanBlock1bis.ReceivedAt,
|
| 1689 |
+
Checked: true,
|
| 1690 |
+
}
|
| 1691 |
+
m.State.
|
| 1692 |
+
On("AddBlock", ctx, stateBlock1bis, m.DbTx).
|
| 1693 |
+
Return(nil).
|
| 1694 |
+
Once()
|
| 1695 |
+
|
| 1696 |
+
m.State.
|
| 1697 |
+
On("GetStoredFlushID", ctx).
|
| 1698 |
+
Return(uint64(1), cProverIDExecution, nil).
|
| 1699 |
+
Once()
|
| 1700 |
+
|
| 1701 |
+
m.DbTx.
|
| 1702 |
+
On("Commit", ctx).
|
| 1703 |
+
Return(nil).
|
| 1704 |
+
Once()
|
| 1705 |
+
|
| 1706 |
+
m.State.
|
| 1707 |
+
On("BeginStateTransaction", ctx).
|
| 1708 |
+
Return(m.DbTx, nil).
|
| 1709 |
+
Once()
|
| 1710 |
+
|
| 1711 |
+
stateBlock2bis := &state.Block{
|
| 1712 |
+
BlockNumber: ethermanBlock2bis.BlockNumber,
|
| 1713 |
+
BlockHash: ethermanBlock2bis.BlockHash,
|
| 1714 |
+
ParentHash: ethermanBlock2bis.ParentHash,
|
| 1715 |
+
ReceivedAt: ethermanBlock2bis.ReceivedAt,
|
| 1716 |
+
Checked: true,
|
| 1717 |
+
}
|
| 1718 |
+
m.State.
|
| 1719 |
+
On("AddBlock", ctx, stateBlock2bis, m.DbTx).
|
| 1720 |
+
Return(nil).
|
| 1721 |
+
Once()
|
| 1722 |
+
|
| 1723 |
+
m.DbTx.
|
| 1724 |
+
On("Commit", ctx).
|
| 1725 |
+
Run(func(args mock.Arguments) {
|
| 1726 |
+
sync.Stop()
|
| 1727 |
+
ctx.Done()
|
| 1728 |
+
}).
|
| 1729 |
+
Return(nil).
|
| 1730 |
+
Once()
|
| 1731 |
+
}).
|
| 1732 |
+
Return(m.DbTx, nil).
|
| 1733 |
+
Once()
|
| 1734 |
+
|
| 1735 |
+
err = sync.Sync()
|
| 1736 |
+
require.NoError(t, err)
|
| 1737 |
+
}
|
| 1738 |
+
|
| 1739 |
+
func TestLatestSyncedBlockEmptyWithExtraReorg(t *testing.T) {
|
| 1740 |
+
genesis := state.Genesis{
|
| 1741 |
+
RollupBlockNumber: uint64(0),
|
| 1742 |
+
}
|
| 1743 |
+
cfg := Config{
|
| 1744 |
+
SyncInterval: cfgTypes.Duration{Duration: 1 * time.Second},
|
| 1745 |
+
SyncChunkSize: 3,
|
| 1746 |
+
L1SynchronizationMode: SequentialMode,
|
| 1747 |
+
SyncBlockProtection: "latest",
|
| 1748 |
+
L1BlockCheck: L1BlockCheckConfig{
|
| 1749 |
+
Enable: false,
|
| 1750 |
+
},
|
| 1751 |
+
}
|
| 1752 |
+
|
| 1753 |
+
m := mocks{
|
| 1754 |
+
Etherman: mock_syncinterfaces.NewEthermanFullInterface(t),
|
| 1755 |
+
State: mock_syncinterfaces.NewStateFullInterface(t),
|
| 1756 |
+
Pool: mock_syncinterfaces.NewPoolInterface(t),
|
| 1757 |
+
DbTx: syncMocks.NewDbTxMock(t),
|
| 1758 |
+
ZKEVMClient: mock_syncinterfaces.NewZKEVMClientInterface(t),
|
| 1759 |
+
EthTxManager: mock_syncinterfaces.NewEthTxManager(t),
|
| 1760 |
+
}
|
| 1761 |
+
ethermanForL1 := []syncinterfaces.EthermanFullInterface{m.Etherman}
|
| 1762 |
+
sync, err := NewSynchronizer(false, m.Etherman, ethermanForL1, m.State, m.Pool, m.EthTxManager, m.ZKEVMClient, m.zkEVMClientEthereumCompatible, nil, genesis, cfg, false)
|
| 1763 |
+
require.NoError(t, err)
|
| 1764 |
+
|
| 1765 |
+
// state preparation
|
| 1766 |
+
ctxMatchBy := mock.MatchedBy(func(ctx context.Context) bool { return ctx != nil })
|
| 1767 |
+
forkIdInterval := state.ForkIDInterval{
|
| 1768 |
+
ForkId: 9,
|
| 1769 |
+
FromBatchNumber: 0,
|
| 1770 |
+
ToBatchNumber: math.MaxUint64,
|
| 1771 |
+
}
|
| 1772 |
+
m.State.EXPECT().GetForkIDInMemory(uint64(9)).Return(&forkIdInterval)
|
| 1773 |
+
|
| 1774 |
+
m.State.
|
| 1775 |
+
On("BeginStateTransaction", ctxMatchBy).
|
| 1776 |
+
Run(func(args mock.Arguments) {
|
| 1777 |
+
ctx := args[0].(context.Context)
|
| 1778 |
+
parentHash := common.HexToHash("0x111")
|
| 1779 |
+
ethHeader0 := ðTypes.Header{Number: big.NewInt(0), ParentHash: parentHash}
|
| 1780 |
+
ethBlock0 := ethTypes.NewBlockWithHeader(ethHeader0)
|
| 1781 |
+
ethHeader1 := ðTypes.Header{Number: big.NewInt(1), ParentHash: ethBlock0.Hash()}
|
| 1782 |
+
ethBlock1 := ethTypes.NewBlockWithHeader(ethHeader1)
|
| 1783 |
+
ethHeader1bis := ðTypes.Header{Number: big.NewInt(1), ParentHash: ethBlock0.Hash(), Time: 0, GasUsed: 10}
|
| 1784 |
+
ethBlock1bis := ethTypes.NewBlockWithHeader(ethHeader1bis)
|
| 1785 |
+
ethHeader2 := ðTypes.Header{Number: big.NewInt(2), ParentHash: ethBlock1.Hash()}
|
| 1786 |
+
ethBlock2 := ethTypes.NewBlockWithHeader(ethHeader2)
|
| 1787 |
+
ethHeader3 := ðTypes.Header{Number: big.NewInt(3), ParentHash: ethBlock2.Hash()}
|
| 1788 |
+
ethBlock3 := ethTypes.NewBlockWithHeader(ethHeader3)
|
| 1789 |
+
|
| 1790 |
+
lastBlock0 := &state.Block{BlockHash: ethBlock0.Hash(), BlockNumber: ethBlock0.Number().Uint64(), ParentHash: ethBlock0.ParentHash()}
|
| 1791 |
+
lastBlock1 := &state.Block{BlockHash: ethBlock1.Hash(), BlockNumber: ethBlock1.Number().Uint64(), ParentHash: ethBlock1.ParentHash()}
|
| 1792 |
+
lastBlock2 := &state.Block{BlockHash: ethBlock2.Hash(), BlockNumber: ethBlock2.Number().Uint64(), ParentHash: ethBlock2.ParentHash()}
|
| 1793 |
+
|
| 1794 |
+
m.State.
|
| 1795 |
+
On("GetForkIDByBatchNumber", mock.Anything).
|
| 1796 |
+
Return(uint64(9), nil).
|
| 1797 |
+
Maybe()
|
| 1798 |
+
m.State.
|
| 1799 |
+
On("GetLastBlock", ctx, m.DbTx).
|
| 1800 |
+
Return(lastBlock2, nil).
|
| 1801 |
+
Once()
|
| 1802 |
+
|
| 1803 |
+
m.State.
|
| 1804 |
+
On("GetLastBatchNumber", ctx, m.DbTx).
|
| 1805 |
+
Return(uint64(10), nil).
|
| 1806 |
+
Once()
|
| 1807 |
+
|
| 1808 |
+
m.State.
|
| 1809 |
+
On("SetInitSyncBatch", ctx, uint64(10), m.DbTx).
|
| 1810 |
+
Return(nil).
|
| 1811 |
+
Once()
|
| 1812 |
+
|
| 1813 |
+
m.DbTx.
|
| 1814 |
+
On("Commit", ctx).
|
| 1815 |
+
Return(nil).
|
| 1816 |
+
Once()
|
| 1817 |
+
|
| 1818 |
+
m.Etherman.
|
| 1819 |
+
On("GetLatestBatchNumber").
|
| 1820 |
+
Return(uint64(10), nil)
|
| 1821 |
+
|
| 1822 |
+
var nilDbTx pgx.Tx
|
| 1823 |
+
m.State.
|
| 1824 |
+
On("GetLastBatchNumber", ctx, nilDbTx).
|
| 1825 |
+
Return(uint64(10), nil)
|
| 1826 |
+
|
| 1827 |
+
m.Etherman.
|
| 1828 |
+
On("GetLatestVerifiedBatchNum").
|
| 1829 |
+
Return(uint64(10), nil)
|
| 1830 |
+
|
| 1831 |
+
m.State.
|
| 1832 |
+
On("SetLastBatchInfoSeenOnEthereum", ctx, uint64(10), uint64(10), nilDbTx).
|
| 1833 |
+
Return(nil)
|
| 1834 |
+
|
| 1835 |
+
m.Etherman.
|
| 1836 |
+
On("EthBlockByNumber", ctx, lastBlock2.BlockNumber).
|
| 1837 |
+
Return(ethBlock2, nil).
|
| 1838 |
+
Once()
|
| 1839 |
+
|
| 1840 |
+
m.ZKEVMClient.
|
| 1841 |
+
On("BatchNumber", ctx).
|
| 1842 |
+
Return(uint64(1), nil).
|
| 1843 |
+
Once()
|
| 1844 |
+
|
| 1845 |
+
n := big.NewInt(rpc.LatestBlockNumber.Int64())
|
| 1846 |
+
m.Etherman.
|
| 1847 |
+
On("HeaderByNumber", mock.Anything, n).
|
| 1848 |
+
Return(ethHeader3, nil).
|
| 1849 |
+
Once()
|
| 1850 |
+
|
| 1851 |
+
m.Etherman.
|
| 1852 |
+
On("EthBlockByNumber", ctx, lastBlock2.BlockNumber).
|
| 1853 |
+
Return(ethBlock2, nil).
|
| 1854 |
+
Once()
|
| 1855 |
+
|
| 1856 |
+
blocks := []etherman.Block{}
|
| 1857 |
+
order := map[common.Hash][]etherman.Order{}
|
| 1858 |
+
|
| 1859 |
+
fromBlock := ethBlock2.NumberU64()
|
| 1860 |
+
toBlock := fromBlock + cfg.SyncChunkSize
|
| 1861 |
+
if toBlock > ethBlock3.NumberU64() {
|
| 1862 |
+
toBlock = ethBlock3.NumberU64()
|
| 1863 |
+
}
|
| 1864 |
+
m.Etherman.
|
| 1865 |
+
On("GetRollupInfoByBlockRange", mock.Anything, fromBlock, &toBlock).
|
| 1866 |
+
Return(blocks, order, nil).
|
| 1867 |
+
Once()
|
| 1868 |
+
|
| 1869 |
+
ti := time.Date(2024, 1, 1, 1, 0, 0, 0, time.UTC)
|
| 1870 |
+
var depth uint64 = 1
|
| 1871 |
+
stateBlock1 := &state.Block{
|
| 1872 |
+
BlockNumber: ethBlock1.NumberU64(),
|
| 1873 |
+
BlockHash: ethBlock1.Hash(),
|
| 1874 |
+
ParentHash: ethBlock1.ParentHash(),
|
| 1875 |
+
ReceivedAt: ti,
|
| 1876 |
+
}
|
| 1877 |
+
m.State.
|
| 1878 |
+
On("GetPreviousBlock", ctx, depth, nil).
|
| 1879 |
+
Return(stateBlock1, nil).
|
| 1880 |
+
Once()
|
| 1881 |
+
|
| 1882 |
+
m.Etherman.
|
| 1883 |
+
On("EthBlockByNumber", ctx, lastBlock1.BlockNumber).
|
| 1884 |
+
Return(ethBlock1bis, nil).
|
| 1885 |
+
Once()
|
| 1886 |
+
|
| 1887 |
+
m.State.
|
| 1888 |
+
On("BeginStateTransaction", ctx).
|
| 1889 |
+
Return(m.DbTx, nil).
|
| 1890 |
+
Once()
|
| 1891 |
+
|
| 1892 |
+
stateBlock0 := &state.Block{
|
| 1893 |
+
BlockNumber: ethBlock0.NumberU64(),
|
| 1894 |
+
BlockHash: ethBlock0.Hash(),
|
| 1895 |
+
ParentHash: ethBlock0.ParentHash(),
|
| 1896 |
+
ReceivedAt: ti,
|
| 1897 |
+
}
|
| 1898 |
+
m.State.
|
| 1899 |
+
On("GetPreviousBlock", ctx, depth, m.DbTx).
|
| 1900 |
+
Return(stateBlock0, nil).
|
| 1901 |
+
Once()
|
| 1902 |
+
|
| 1903 |
+
m.DbTx.
|
| 1904 |
+
On("Commit", ctx).
|
| 1905 |
+
Return(nil).
|
| 1906 |
+
Once()
|
| 1907 |
+
|
| 1908 |
+
m.Etherman.
|
| 1909 |
+
On("EthBlockByNumber", ctx, lastBlock0.BlockNumber).
|
| 1910 |
+
Return(ethBlock0, nil).
|
| 1911 |
+
Once()
|
| 1912 |
+
|
| 1913 |
+
m.State.
|
| 1914 |
+
On("BeginStateTransaction", ctx).
|
| 1915 |
+
Return(m.DbTx, nil).
|
| 1916 |
+
Once()
|
| 1917 |
+
|
| 1918 |
+
m.State.
|
| 1919 |
+
On("Reset", ctx, ethBlock0.NumberU64(), m.DbTx).
|
| 1920 |
+
Return(nil).
|
| 1921 |
+
Once()
|
| 1922 |
+
|
| 1923 |
+
m.EthTxManager.
|
| 1924 |
+
On("Reorg", ctx, ethBlock0.NumberU64()+1, m.DbTx).
|
| 1925 |
+
Return(nil).
|
| 1926 |
+
Once()
|
| 1927 |
+
|
| 1928 |
+
m.DbTx.
|
| 1929 |
+
On("Commit", ctx).
|
| 1930 |
+
Return(nil).
|
| 1931 |
+
Once()
|
| 1932 |
+
|
| 1933 |
+
m.Etherman.
|
| 1934 |
+
On("EthBlockByNumber", ctx, lastBlock0.BlockNumber).
|
| 1935 |
+
Return(ethBlock0, nil).
|
| 1936 |
+
Once()
|
| 1937 |
+
|
| 1938 |
+
m.ZKEVMClient.
|
| 1939 |
+
On("BatchNumber", ctx).
|
| 1940 |
+
Return(uint64(1), nil).
|
| 1941 |
+
Once()
|
| 1942 |
+
|
| 1943 |
+
m.Etherman.
|
| 1944 |
+
On("HeaderByNumber", mock.Anything, n).
|
| 1945 |
+
Return(ethHeader3, nil).
|
| 1946 |
+
Once()
|
| 1947 |
+
|
| 1948 |
+
m.Etherman.
|
| 1949 |
+
On("EthBlockByNumber", ctx, lastBlock0.BlockNumber).
|
| 1950 |
+
Return(ethBlock0, nil).
|
| 1951 |
+
Once()
|
| 1952 |
+
|
| 1953 |
+
ethermanBlock0 := etherman.Block{
|
| 1954 |
+
BlockNumber: 0,
|
| 1955 |
+
ReceivedAt: ti,
|
| 1956 |
+
BlockHash: ethBlock0.Hash(),
|
| 1957 |
+
ParentHash: ethBlock0.ParentHash(),
|
| 1958 |
+
}
|
| 1959 |
+
ethermanBlock1bis := etherman.Block{
|
| 1960 |
+
BlockNumber: 1,
|
| 1961 |
+
ReceivedAt: ti,
|
| 1962 |
+
BlockHash: ethBlock1.Hash(),
|
| 1963 |
+
ParentHash: ethBlock1.ParentHash(),
|
| 1964 |
+
}
|
| 1965 |
+
blocks = []etherman.Block{ethermanBlock0, ethermanBlock1bis}
|
| 1966 |
+
fromBlock = 0
|
| 1967 |
+
m.Etherman.
|
| 1968 |
+
On("GetRollupInfoByBlockRange", mock.Anything, fromBlock, &toBlock).
|
| 1969 |
+
Return(blocks, order, nil).
|
| 1970 |
+
Once()
|
| 1971 |
+
|
| 1972 |
+
m.Etherman.
|
| 1973 |
+
On("GetFinalizedBlockNumber", ctx).
|
| 1974 |
+
Return(ethBlock3.NumberU64(), nil).
|
| 1975 |
+
Once()
|
| 1976 |
+
|
| 1977 |
+
m.State.
|
| 1978 |
+
On("BeginStateTransaction", ctx).
|
| 1979 |
+
Return(m.DbTx, nil).
|
| 1980 |
+
Once()
|
| 1981 |
+
|
| 1982 |
+
stateBlock1bis := &state.Block{
|
| 1983 |
+
BlockNumber: ethermanBlock1bis.BlockNumber,
|
| 1984 |
+
BlockHash: ethermanBlock1bis.BlockHash,
|
| 1985 |
+
ParentHash: ethermanBlock1bis.ParentHash,
|
| 1986 |
+
ReceivedAt: ethermanBlock1bis.ReceivedAt,
|
| 1987 |
+
Checked: true,
|
| 1988 |
+
}
|
| 1989 |
+
m.State.
|
| 1990 |
+
On("AddBlock", ctx, stateBlock1bis, m.DbTx).
|
| 1991 |
+
Return(nil).
|
| 1992 |
+
Once()
|
| 1993 |
+
|
| 1994 |
+
m.State.
|
| 1995 |
+
On("GetStoredFlushID", ctx).
|
| 1996 |
+
Return(uint64(1), cProverIDExecution, nil).
|
| 1997 |
+
Once()
|
| 1998 |
+
|
| 1999 |
+
m.DbTx.
|
| 2000 |
+
On("Commit", ctx).
|
| 2001 |
+
Return(nil).
|
| 2002 |
+
Run(func(args mock.Arguments) {
|
| 2003 |
+
sync.Stop()
|
| 2004 |
+
ctx.Done()
|
| 2005 |
+
}).
|
| 2006 |
+
Once()
|
| 2007 |
+
}).
|
| 2008 |
+
Return(m.DbTx, nil).
|
| 2009 |
+
Once()
|
| 2010 |
+
|
| 2011 |
+
err = sync.Sync()
|
| 2012 |
+
require.NoError(t, err)
|
| 2013 |
+
}
|
| 2014 |
+
|
| 2015 |
+
func TestCallFromEmptyBlockAndReorg(t *testing.T) {
|
| 2016 |
+
genesis := state.Genesis{
|
| 2017 |
+
RollupBlockNumber: uint64(0),
|
| 2018 |
+
}
|
| 2019 |
+
cfg := Config{
|
| 2020 |
+
SyncInterval: cfgTypes.Duration{Duration: 1 * time.Second},
|
| 2021 |
+
SyncChunkSize: 3,
|
| 2022 |
+
L1SynchronizationMode: SequentialMode,
|
| 2023 |
+
SyncBlockProtection: "latest",
|
| 2024 |
+
L1BlockCheck: L1BlockCheckConfig{
|
| 2025 |
+
Enable: false,
|
| 2026 |
+
},
|
| 2027 |
+
}
|
| 2028 |
+
|
| 2029 |
+
m := mocks{
|
| 2030 |
+
Etherman: mock_syncinterfaces.NewEthermanFullInterface(t),
|
| 2031 |
+
State: mock_syncinterfaces.NewStateFullInterface(t),
|
| 2032 |
+
Pool: mock_syncinterfaces.NewPoolInterface(t),
|
| 2033 |
+
DbTx: syncMocks.NewDbTxMock(t),
|
| 2034 |
+
ZKEVMClient: mock_syncinterfaces.NewZKEVMClientInterface(t),
|
| 2035 |
+
EthTxManager: mock_syncinterfaces.NewEthTxManager(t),
|
| 2036 |
+
}
|
| 2037 |
+
ethermanForL1 := []syncinterfaces.EthermanFullInterface{m.Etherman}
|
| 2038 |
+
sync, err := NewSynchronizer(false, m.Etherman, ethermanForL1, m.State, m.Pool, m.EthTxManager, m.ZKEVMClient, m.zkEVMClientEthereumCompatible, nil, genesis, cfg, false)
|
| 2039 |
+
require.NoError(t, err)
|
| 2040 |
+
|
| 2041 |
+
// state preparation
|
| 2042 |
+
ctxMatchBy := mock.MatchedBy(func(ctx context.Context) bool { return ctx != nil })
|
| 2043 |
+
forkIdInterval := state.ForkIDInterval{
|
| 2044 |
+
ForkId: 9,
|
| 2045 |
+
FromBatchNumber: 0,
|
| 2046 |
+
ToBatchNumber: math.MaxUint64,
|
| 2047 |
+
}
|
| 2048 |
+
m.State.EXPECT().GetForkIDInMemory(uint64(9)).Return(&forkIdInterval)
|
| 2049 |
+
|
| 2050 |
+
m.State.
|
| 2051 |
+
On("BeginStateTransaction", ctxMatchBy).
|
| 2052 |
+
Run(func(args mock.Arguments) {
|
| 2053 |
+
ctx := args[0].(context.Context)
|
| 2054 |
+
parentHash := common.HexToHash("0x111")
|
| 2055 |
+
ethHeader0 := ðTypes.Header{Number: big.NewInt(0), ParentHash: parentHash}
|
| 2056 |
+
ethBlock0 := ethTypes.NewBlockWithHeader(ethHeader0)
|
| 2057 |
+
ethHeader1bis := ðTypes.Header{Number: big.NewInt(1), ParentHash: ethBlock0.Hash(), Time: 10, GasUsed: 20, Root: common.HexToHash("0x234")}
|
| 2058 |
+
ethBlock1bis := ethTypes.NewBlockWithHeader(ethHeader1bis)
|
| 2059 |
+
ethHeader2bis := ðTypes.Header{Number: big.NewInt(2), ParentHash: ethBlock1bis.Hash()}
|
| 2060 |
+
ethBlock2bis := ethTypes.NewBlockWithHeader(ethHeader2bis)
|
| 2061 |
+
ethHeader1 := ðTypes.Header{Number: big.NewInt(1), ParentHash: ethBlock0.Hash()}
|
| 2062 |
+
ethBlock1 := ethTypes.NewBlockWithHeader(ethHeader1)
|
| 2063 |
+
ethHeader2 := ðTypes.Header{Number: big.NewInt(2), ParentHash: ethBlock1.Hash()}
|
| 2064 |
+
ethBlock2 := ethTypes.NewBlockWithHeader(ethHeader2)
|
| 2065 |
+
|
| 2066 |
+
lastBlock0 := &state.Block{BlockHash: ethBlock0.Hash(), BlockNumber: ethBlock0.Number().Uint64(), ParentHash: ethBlock0.ParentHash()}
|
| 2067 |
+
lastBlock1 := &state.Block{BlockHash: ethBlock1.Hash(), BlockNumber: ethBlock1.Number().Uint64(), ParentHash: ethBlock1.ParentHash()}
|
| 2068 |
+
|
| 2069 |
+
m.State.
|
| 2070 |
+
On("GetForkIDByBatchNumber", mock.Anything).
|
| 2071 |
+
Return(uint64(9), nil).
|
| 2072 |
+
Maybe()
|
| 2073 |
+
m.State.
|
| 2074 |
+
On("GetLastBlock", ctx, m.DbTx).
|
| 2075 |
+
Return(lastBlock1, nil).
|
| 2076 |
+
Once()
|
| 2077 |
+
|
| 2078 |
+
m.State.
|
| 2079 |
+
On("GetLastBatchNumber", ctx, m.DbTx).
|
| 2080 |
+
Return(uint64(10), nil).
|
| 2081 |
+
Once()
|
| 2082 |
+
|
| 2083 |
+
m.State.
|
| 2084 |
+
On("SetInitSyncBatch", ctx, uint64(10), m.DbTx).
|
| 2085 |
+
Return(nil).
|
| 2086 |
+
Once()
|
| 2087 |
+
|
| 2088 |
+
m.DbTx.
|
| 2089 |
+
On("Commit", ctx).
|
| 2090 |
+
Return(nil).
|
| 2091 |
+
Once()
|
| 2092 |
+
|
| 2093 |
+
m.Etherman.
|
| 2094 |
+
On("GetLatestBatchNumber").
|
| 2095 |
+
Return(uint64(10), nil)
|
| 2096 |
+
|
| 2097 |
+
var nilDbTx pgx.Tx
|
| 2098 |
+
m.State.
|
| 2099 |
+
On("GetLastBatchNumber", ctx, nilDbTx).
|
| 2100 |
+
Return(uint64(10), nil)
|
| 2101 |
+
|
| 2102 |
+
m.Etherman.
|
| 2103 |
+
On("GetLatestVerifiedBatchNum").
|
| 2104 |
+
Return(uint64(10), nil)
|
| 2105 |
+
|
| 2106 |
+
m.State.
|
| 2107 |
+
On("SetLastBatchInfoSeenOnEthereum", ctx, uint64(10), uint64(10), nilDbTx).
|
| 2108 |
+
Return(nil)
|
| 2109 |
+
|
| 2110 |
+
m.Etherman.
|
| 2111 |
+
On("EthBlockByNumber", ctx, lastBlock1.BlockNumber).
|
| 2112 |
+
Return(ethBlock1, nil).
|
| 2113 |
+
Once()
|
| 2114 |
+
|
| 2115 |
+
m.ZKEVMClient.
|
| 2116 |
+
On("BatchNumber", ctx).
|
| 2117 |
+
Return(uint64(1), nil).
|
| 2118 |
+
Once()
|
| 2119 |
+
|
| 2120 |
+
n := big.NewInt(rpc.LatestBlockNumber.Int64())
|
| 2121 |
+
|
| 2122 |
+
m.Etherman.
|
| 2123 |
+
On("EthBlockByNumber", ctx, lastBlock1.BlockNumber).
|
| 2124 |
+
Return(ethBlock1, nil).
|
| 2125 |
+
Once()
|
| 2126 |
+
|
| 2127 |
+
m.Etherman.
|
| 2128 |
+
On("HeaderByNumber", mock.Anything, n).
|
| 2129 |
+
Return(ethHeader2bis, nil).
|
| 2130 |
+
Once()
|
| 2131 |
+
|
| 2132 |
+
// m.Etherman.
|
| 2133 |
+
// On("EthBlockByNumber", ctx, lastBlock1.BlockNumber).
|
| 2134 |
+
// Return(ethBlock1, nil).
|
| 2135 |
+
// Once()
|
| 2136 |
+
|
| 2137 |
+
ti := time.Date(2024, 1, 1, 1, 0, 0, 0, time.UTC)
|
| 2138 |
+
|
| 2139 |
+
ethermanBlock0 := etherman.Block{
|
| 2140 |
+
BlockNumber: 0,
|
| 2141 |
+
ReceivedAt: ti,
|
| 2142 |
+
BlockHash: ethBlock0.Hash(),
|
| 2143 |
+
ParentHash: ethBlock0.ParentHash(),
|
| 2144 |
+
}
|
| 2145 |
+
ethermanBlock2bis := etherman.Block{
|
| 2146 |
+
BlockNumber: 2,
|
| 2147 |
+
ReceivedAt: ti,
|
| 2148 |
+
BlockHash: ethBlock2bis.Hash(),
|
| 2149 |
+
ParentHash: ethBlock2bis.ParentHash(),
|
| 2150 |
+
}
|
| 2151 |
+
blocks := []etherman.Block{ethermanBlock2bis}
|
| 2152 |
+
order := map[common.Hash][]etherman.Order{}
|
| 2153 |
+
|
| 2154 |
+
fromBlock := ethBlock1.NumberU64()
|
| 2155 |
+
toBlock := fromBlock + cfg.SyncChunkSize
|
| 2156 |
+
if toBlock > ethBlock2.NumberU64() {
|
| 2157 |
+
toBlock = ethBlock2.NumberU64()
|
| 2158 |
+
}
|
| 2159 |
+
m.Etherman.
|
| 2160 |
+
On("GetRollupInfoByBlockRange", mock.Anything, fromBlock, &toBlock).
|
| 2161 |
+
Return(blocks, order, nil).
|
| 2162 |
+
Once()
|
| 2163 |
+
|
| 2164 |
+
m.State.
|
| 2165 |
+
On("BeginStateTransaction", ctx).
|
| 2166 |
+
Return(m.DbTx, nil).
|
| 2167 |
+
Once()
|
| 2168 |
+
|
| 2169 |
+
var depth uint64 = 1
|
| 2170 |
+
stateBlock0 := &state.Block{
|
| 2171 |
+
BlockNumber: ethBlock0.NumberU64(),
|
| 2172 |
+
BlockHash: ethBlock0.Hash(),
|
| 2173 |
+
ParentHash: ethBlock0.ParentHash(),
|
| 2174 |
+
ReceivedAt: ti,
|
| 2175 |
+
}
|
| 2176 |
+
m.State.
|
| 2177 |
+
On("GetPreviousBlock", ctx, depth, m.DbTx).
|
| 2178 |
+
Return(stateBlock0, nil).
|
| 2179 |
+
Once()
|
| 2180 |
+
|
| 2181 |
+
m.DbTx.
|
| 2182 |
+
On("Commit", ctx).
|
| 2183 |
+
Return(nil).
|
| 2184 |
+
Once()
|
| 2185 |
+
|
| 2186 |
+
m.Etherman.
|
| 2187 |
+
On("EthBlockByNumber", ctx, lastBlock0.BlockNumber).
|
| 2188 |
+
Return(ethBlock0, nil).
|
| 2189 |
+
Once()
|
| 2190 |
+
|
| 2191 |
+
m.State.
|
| 2192 |
+
On("BeginStateTransaction", ctx).
|
| 2193 |
+
Return(m.DbTx, nil).
|
| 2194 |
+
Once()
|
| 2195 |
+
|
| 2196 |
+
m.State.
|
| 2197 |
+
On("Reset", ctx, ethBlock0.NumberU64(), m.DbTx).
|
| 2198 |
+
Return(nil).
|
| 2199 |
+
Once()
|
| 2200 |
+
|
| 2201 |
+
m.EthTxManager.
|
| 2202 |
+
On("Reorg", ctx, ethBlock0.NumberU64()+1, m.DbTx).
|
| 2203 |
+
Return(nil).
|
| 2204 |
+
Once()
|
| 2205 |
+
|
| 2206 |
+
m.DbTx.
|
| 2207 |
+
On("Commit", ctx).
|
| 2208 |
+
Return(nil).
|
| 2209 |
+
Once()
|
| 2210 |
+
|
| 2211 |
+
m.Etherman.
|
| 2212 |
+
On("EthBlockByNumber", ctx, lastBlock0.BlockNumber).
|
| 2213 |
+
Return(ethBlock0, nil).
|
| 2214 |
+
Once()
|
| 2215 |
+
|
| 2216 |
+
m.ZKEVMClient.
|
| 2217 |
+
On("BatchNumber", ctx).
|
| 2218 |
+
Return(uint64(1), nil).
|
| 2219 |
+
Once()
|
| 2220 |
+
|
| 2221 |
+
m.Etherman.
|
| 2222 |
+
On("EthBlockByNumber", ctx, lastBlock0.BlockNumber).
|
| 2223 |
+
Return(ethBlock0, nil).
|
| 2224 |
+
Once()
|
| 2225 |
+
|
| 2226 |
+
m.Etherman.
|
| 2227 |
+
On("HeaderByNumber", mock.Anything, n).
|
| 2228 |
+
Return(ethHeader2bis, nil).
|
| 2229 |
+
Once()
|
| 2230 |
+
|
| 2231 |
+
blocks = []etherman.Block{ethermanBlock0, ethermanBlock2bis}
|
| 2232 |
+
fromBlock = ethBlock0.NumberU64()
|
| 2233 |
+
toBlock = fromBlock + cfg.SyncChunkSize
|
| 2234 |
+
if toBlock > ethBlock2.NumberU64() {
|
| 2235 |
+
toBlock = ethBlock2.NumberU64()
|
| 2236 |
+
}
|
| 2237 |
+
m.Etherman.
|
| 2238 |
+
On("GetRollupInfoByBlockRange", mock.Anything, fromBlock, &toBlock).
|
| 2239 |
+
Return(blocks, order, nil).
|
| 2240 |
+
Once()
|
| 2241 |
+
|
| 2242 |
+
m.Etherman.
|
| 2243 |
+
On("GetFinalizedBlockNumber", ctx).
|
| 2244 |
+
Return(ethBlock2bis.NumberU64(), nil).
|
| 2245 |
+
Once()
|
| 2246 |
+
|
| 2247 |
+
m.State.
|
| 2248 |
+
On("BeginStateTransaction", ctx).
|
| 2249 |
+
Return(m.DbTx, nil).
|
| 2250 |
+
Once()
|
| 2251 |
+
|
| 2252 |
+
stateBlock2bis := &state.Block{
|
| 2253 |
+
BlockNumber: ethermanBlock2bis.BlockNumber,
|
| 2254 |
+
BlockHash: ethermanBlock2bis.BlockHash,
|
| 2255 |
+
ParentHash: ethermanBlock2bis.ParentHash,
|
| 2256 |
+
ReceivedAt: ethermanBlock2bis.ReceivedAt,
|
| 2257 |
+
Checked: true,
|
| 2258 |
+
}
|
| 2259 |
+
m.State.
|
| 2260 |
+
On("AddBlock", ctx, stateBlock2bis, m.DbTx).
|
| 2261 |
+
Return(nil).
|
| 2262 |
+
Once()
|
| 2263 |
+
|
| 2264 |
+
m.State.
|
| 2265 |
+
On("GetStoredFlushID", ctx).
|
| 2266 |
+
Return(uint64(1), cProverIDExecution, nil).
|
| 2267 |
+
Once()
|
| 2268 |
+
|
| 2269 |
+
m.DbTx.
|
| 2270 |
+
On("Commit", ctx).
|
| 2271 |
+
Run(func(args mock.Arguments) {
|
| 2272 |
+
sync.Stop()
|
| 2273 |
+
ctx.Done()
|
| 2274 |
+
}).
|
| 2275 |
+
Return(nil).
|
| 2276 |
+
Once()
|
| 2277 |
+
}).
|
| 2278 |
+
Return(m.DbTx, nil).
|
| 2279 |
+
Once()
|
| 2280 |
+
|
| 2281 |
+
err = sync.Sync()
|
| 2282 |
+
require.NoError(t, err)
|
| 2283 |
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// SPDX-License-Identifier: GPL-3.0
|
| 2 |
+
|
| 3 |
+
pragma solidity >=0.7.0 <0.9.0;
|
| 4 |
+
|
| 5 |
+
contract CounterAndBlock {
|
| 6 |
+
uint public count;
|
| 7 |
+
|
| 8 |
+
function increment() external {
|
| 9 |
+
count += 1;
|
| 10 |
+
}
|
| 11 |
+
|
| 12 |
+
function getCount() public view returns (uint, uint) {
|
| 13 |
+
return (count, block.timestamp);
|
| 14 |
+
}
|
| 15 |
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// SPDX-License-Identifier: MIT
|
| 2 |
+
pragma solidity >=0.7.0 <0.9.0;
|
| 3 |
+
|
| 4 |
+
contract customModExp {
|
| 5 |
+
bytes32 hashResult;
|
| 6 |
+
address retEcrecover;
|
| 7 |
+
bytes dataResult;
|
| 8 |
+
uint256 dataRes;
|
| 9 |
+
|
| 10 |
+
bytes32[10] arrayStorage;
|
| 11 |
+
|
| 12 |
+
function modExpGeneric(bytes memory input) public {
|
| 13 |
+
bytes32[10] memory output;
|
| 14 |
+
|
| 15 |
+
assembly {
|
| 16 |
+
let success := staticcall(gas(), 0x05, add(input, 32), mload(input), output, 0x140)
|
| 17 |
+
sstore(0x00, success)
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
for (uint i = 0; i < 10; i++) {
|
| 21 |
+
arrayStorage[i] = output[i];
|
| 22 |
+
}
|
| 23 |
+
}
|
| 24 |
+
}
|
|
@@ -0,0 +1,287 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Code generated - DO NOT EDIT.
|
| 2 |
+
// This file is a generated binding and any manual changes will be lost.
|
| 3 |
+
|
| 4 |
+
package CounterAndBlock
|
| 5 |
+
|
| 6 |
+
import (
|
| 7 |
+
"errors"
|
| 8 |
+
"math/big"
|
| 9 |
+
"strings"
|
| 10 |
+
|
| 11 |
+
ethereum "github.com/ethereum/go-ethereum"
|
| 12 |
+
"github.com/ethereum/go-ethereum/accounts/abi"
|
| 13 |
+
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
| 14 |
+
"github.com/ethereum/go-ethereum/common"
|
| 15 |
+
"github.com/ethereum/go-ethereum/core/types"
|
| 16 |
+
"github.com/ethereum/go-ethereum/event"
|
| 17 |
+
)
|
| 18 |
+
|
| 19 |
+
// Reference imports to suppress errors if they are not otherwise used.
|
| 20 |
+
var (
|
| 21 |
+
_ = errors.New
|
| 22 |
+
_ = big.NewInt
|
| 23 |
+
_ = strings.NewReader
|
| 24 |
+
_ = ethereum.NotFound
|
| 25 |
+
_ = bind.Bind
|
| 26 |
+
_ = common.Big1
|
| 27 |
+
_ = types.BloomLookup
|
| 28 |
+
_ = event.NewSubscription
|
| 29 |
+
_ = abi.ConvertType
|
| 30 |
+
)
|
| 31 |
+
|
| 32 |
+
// CounterAndBlockMetaData contains all meta data concerning the CounterAndBlock contract.
|
| 33 |
+
var CounterAndBlockMetaData = &bind.MetaData{
|
| 34 |
+
ABI: "[{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"increment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
|
| 35 |
+
Bin: "0x608060405234801561001057600080fd5b5060eb8061001f6000396000f3fe6080604052348015600f57600080fd5b5060043610603c5760003560e01c806306661abd146041578063a87d942c14605c578063d09de08a146071575b600080fd5b604960005481565b6040519081526020015b60405180910390f35b60005460408051918252426020830152016053565b60776079565b005b6001600080828254608991906090565b9091555050565b6000821982111560b057634e487b7160e01b600052601160045260246000fd5b50019056fea26469706673582212205aa9aebefdfb857d27d7bdc8475c08138617cc37e78c2e6bd98acb9a1484994964736f6c634300080c0033",
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
// CounterAndBlockABI is the input ABI used to generate the binding from.
|
| 39 |
+
// Deprecated: Use CounterAndBlockMetaData.ABI instead.
|
| 40 |
+
var CounterAndBlockABI = CounterAndBlockMetaData.ABI
|
| 41 |
+
|
| 42 |
+
// CounterAndBlockBin is the compiled bytecode used for deploying new contracts.
|
| 43 |
+
// Deprecated: Use CounterAndBlockMetaData.Bin instead.
|
| 44 |
+
var CounterAndBlockBin = CounterAndBlockMetaData.Bin
|
| 45 |
+
|
| 46 |
+
// DeployCounterAndBlock deploys a new Ethereum contract, binding an instance of CounterAndBlock to it.
|
| 47 |
+
func DeployCounterAndBlock(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *CounterAndBlock, error) {
|
| 48 |
+
parsed, err := CounterAndBlockMetaData.GetAbi()
|
| 49 |
+
if err != nil {
|
| 50 |
+
return common.Address{}, nil, nil, err
|
| 51 |
+
}
|
| 52 |
+
if parsed == nil {
|
| 53 |
+
return common.Address{}, nil, nil, errors.New("GetABI returned nil")
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(CounterAndBlockBin), backend)
|
| 57 |
+
if err != nil {
|
| 58 |
+
return common.Address{}, nil, nil, err
|
| 59 |
+
}
|
| 60 |
+
return address, tx, &CounterAndBlock{CounterAndBlockCaller: CounterAndBlockCaller{contract: contract}, CounterAndBlockTransactor: CounterAndBlockTransactor{contract: contract}, CounterAndBlockFilterer: CounterAndBlockFilterer{contract: contract}}, nil
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
// CounterAndBlock is an auto generated Go binding around an Ethereum contract.
|
| 64 |
+
type CounterAndBlock struct {
|
| 65 |
+
CounterAndBlockCaller // Read-only binding to the contract
|
| 66 |
+
CounterAndBlockTransactor // Write-only binding to the contract
|
| 67 |
+
CounterAndBlockFilterer // Log filterer for contract events
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
// CounterAndBlockCaller is an auto generated read-only Go binding around an Ethereum contract.
|
| 71 |
+
type CounterAndBlockCaller struct {
|
| 72 |
+
contract *bind.BoundContract // Generic contract wrapper for the low level calls
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
// CounterAndBlockTransactor is an auto generated write-only Go binding around an Ethereum contract.
|
| 76 |
+
type CounterAndBlockTransactor struct {
|
| 77 |
+
contract *bind.BoundContract // Generic contract wrapper for the low level calls
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
// CounterAndBlockFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
|
| 81 |
+
type CounterAndBlockFilterer struct {
|
| 82 |
+
contract *bind.BoundContract // Generic contract wrapper for the low level calls
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
// CounterAndBlockSession is an auto generated Go binding around an Ethereum contract,
|
| 86 |
+
// with pre-set call and transact options.
|
| 87 |
+
type CounterAndBlockSession struct {
|
| 88 |
+
Contract *CounterAndBlock // Generic contract binding to set the session for
|
| 89 |
+
CallOpts bind.CallOpts // Call options to use throughout this session
|
| 90 |
+
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
// CounterAndBlockCallerSession is an auto generated read-only Go binding around an Ethereum contract,
|
| 94 |
+
// with pre-set call options.
|
| 95 |
+
type CounterAndBlockCallerSession struct {
|
| 96 |
+
Contract *CounterAndBlockCaller // Generic contract caller binding to set the session for
|
| 97 |
+
CallOpts bind.CallOpts // Call options to use throughout this session
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
// CounterAndBlockTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
|
| 101 |
+
// with pre-set transact options.
|
| 102 |
+
type CounterAndBlockTransactorSession struct {
|
| 103 |
+
Contract *CounterAndBlockTransactor // Generic contract transactor binding to set the session for
|
| 104 |
+
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
|
| 105 |
+
}
|
| 106 |
+
|
| 107 |
+
// CounterAndBlockRaw is an auto generated low-level Go binding around an Ethereum contract.
|
| 108 |
+
type CounterAndBlockRaw struct {
|
| 109 |
+
Contract *CounterAndBlock // Generic contract binding to access the raw methods on
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
// CounterAndBlockCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
|
| 113 |
+
type CounterAndBlockCallerRaw struct {
|
| 114 |
+
Contract *CounterAndBlockCaller // Generic read-only contract binding to access the raw methods on
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
// CounterAndBlockTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
|
| 118 |
+
type CounterAndBlockTransactorRaw struct {
|
| 119 |
+
Contract *CounterAndBlockTransactor // Generic write-only contract binding to access the raw methods on
|
| 120 |
+
}
|
| 121 |
+
|
| 122 |
+
// NewCounterAndBlock creates a new instance of CounterAndBlock, bound to a specific deployed contract.
|
| 123 |
+
func NewCounterAndBlock(address common.Address, backend bind.ContractBackend) (*CounterAndBlock, error) {
|
| 124 |
+
contract, err := bindCounterAndBlock(address, backend, backend, backend)
|
| 125 |
+
if err != nil {
|
| 126 |
+
return nil, err
|
| 127 |
+
}
|
| 128 |
+
return &CounterAndBlock{CounterAndBlockCaller: CounterAndBlockCaller{contract: contract}, CounterAndBlockTransactor: CounterAndBlockTransactor{contract: contract}, CounterAndBlockFilterer: CounterAndBlockFilterer{contract: contract}}, nil
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
// NewCounterAndBlockCaller creates a new read-only instance of CounterAndBlock, bound to a specific deployed contract.
|
| 132 |
+
func NewCounterAndBlockCaller(address common.Address, caller bind.ContractCaller) (*CounterAndBlockCaller, error) {
|
| 133 |
+
contract, err := bindCounterAndBlock(address, caller, nil, nil)
|
| 134 |
+
if err != nil {
|
| 135 |
+
return nil, err
|
| 136 |
+
}
|
| 137 |
+
return &CounterAndBlockCaller{contract: contract}, nil
|
| 138 |
+
}
|
| 139 |
+
|
| 140 |
+
// NewCounterAndBlockTransactor creates a new write-only instance of CounterAndBlock, bound to a specific deployed contract.
|
| 141 |
+
func NewCounterAndBlockTransactor(address common.Address, transactor bind.ContractTransactor) (*CounterAndBlockTransactor, error) {
|
| 142 |
+
contract, err := bindCounterAndBlock(address, nil, transactor, nil)
|
| 143 |
+
if err != nil {
|
| 144 |
+
return nil, err
|
| 145 |
+
}
|
| 146 |
+
return &CounterAndBlockTransactor{contract: contract}, nil
|
| 147 |
+
}
|
| 148 |
+
|
| 149 |
+
// NewCounterAndBlockFilterer creates a new log filterer instance of CounterAndBlock, bound to a specific deployed contract.
|
| 150 |
+
func NewCounterAndBlockFilterer(address common.Address, filterer bind.ContractFilterer) (*CounterAndBlockFilterer, error) {
|
| 151 |
+
contract, err := bindCounterAndBlock(address, nil, nil, filterer)
|
| 152 |
+
if err != nil {
|
| 153 |
+
return nil, err
|
| 154 |
+
}
|
| 155 |
+
return &CounterAndBlockFilterer{contract: contract}, nil
|
| 156 |
+
}
|
| 157 |
+
|
| 158 |
+
// bindCounterAndBlock binds a generic wrapper to an already deployed contract.
|
| 159 |
+
func bindCounterAndBlock(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
|
| 160 |
+
parsed, err := CounterAndBlockMetaData.GetAbi()
|
| 161 |
+
if err != nil {
|
| 162 |
+
return nil, err
|
| 163 |
+
}
|
| 164 |
+
return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
|
| 165 |
+
}
|
| 166 |
+
|
| 167 |
+
// Call invokes the (constant) contract method with params as input values and
|
| 168 |
+
// sets the output to result. The result type might be a single field for simple
|
| 169 |
+
// returns, a slice of interfaces for anonymous returns and a struct for named
|
| 170 |
+
// returns.
|
| 171 |
+
func (_CounterAndBlock *CounterAndBlockRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
|
| 172 |
+
return _CounterAndBlock.Contract.CounterAndBlockCaller.contract.Call(opts, result, method, params...)
|
| 173 |
+
}
|
| 174 |
+
|
| 175 |
+
// Transfer initiates a plain transaction to move funds to the contract, calling
|
| 176 |
+
// its default method if one is available.
|
| 177 |
+
func (_CounterAndBlock *CounterAndBlockRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
|
| 178 |
+
return _CounterAndBlock.Contract.CounterAndBlockTransactor.contract.Transfer(opts)
|
| 179 |
+
}
|
| 180 |
+
|
| 181 |
+
// Transact invokes the (paid) contract method with params as input values.
|
| 182 |
+
func (_CounterAndBlock *CounterAndBlockRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
|
| 183 |
+
return _CounterAndBlock.Contract.CounterAndBlockTransactor.contract.Transact(opts, method, params...)
|
| 184 |
+
}
|
| 185 |
+
|
| 186 |
+
// Call invokes the (constant) contract method with params as input values and
|
| 187 |
+
// sets the output to result. The result type might be a single field for simple
|
| 188 |
+
// returns, a slice of interfaces for anonymous returns and a struct for named
|
| 189 |
+
// returns.
|
| 190 |
+
func (_CounterAndBlock *CounterAndBlockCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
|
| 191 |
+
return _CounterAndBlock.Contract.contract.Call(opts, result, method, params...)
|
| 192 |
+
}
|
| 193 |
+
|
| 194 |
+
// Transfer initiates a plain transaction to move funds to the contract, calling
|
| 195 |
+
// its default method if one is available.
|
| 196 |
+
func (_CounterAndBlock *CounterAndBlockTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
|
| 197 |
+
return _CounterAndBlock.Contract.contract.Transfer(opts)
|
| 198 |
+
}
|
| 199 |
+
|
| 200 |
+
// Transact invokes the (paid) contract method with params as input values.
|
| 201 |
+
func (_CounterAndBlock *CounterAndBlockTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
|
| 202 |
+
return _CounterAndBlock.Contract.contract.Transact(opts, method, params...)
|
| 203 |
+
}
|
| 204 |
+
|
| 205 |
+
// Count is a free data retrieval call binding the contract method 0x06661abd.
|
| 206 |
+
//
|
| 207 |
+
// Solidity: function count() view returns(uint256)
|
| 208 |
+
func (_CounterAndBlock *CounterAndBlockCaller) Count(opts *bind.CallOpts) (*big.Int, error) {
|
| 209 |
+
var out []interface{}
|
| 210 |
+
err := _CounterAndBlock.contract.Call(opts, &out, "count")
|
| 211 |
+
|
| 212 |
+
if err != nil {
|
| 213 |
+
return *new(*big.Int), err
|
| 214 |
+
}
|
| 215 |
+
|
| 216 |
+
out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
|
| 217 |
+
|
| 218 |
+
return out0, err
|
| 219 |
+
|
| 220 |
+
}
|
| 221 |
+
|
| 222 |
+
// Count is a free data retrieval call binding the contract method 0x06661abd.
|
| 223 |
+
//
|
| 224 |
+
// Solidity: function count() view returns(uint256)
|
| 225 |
+
func (_CounterAndBlock *CounterAndBlockSession) Count() (*big.Int, error) {
|
| 226 |
+
return _CounterAndBlock.Contract.Count(&_CounterAndBlock.CallOpts)
|
| 227 |
+
}
|
| 228 |
+
|
| 229 |
+
// Count is a free data retrieval call binding the contract method 0x06661abd.
|
| 230 |
+
//
|
| 231 |
+
// Solidity: function count() view returns(uint256)
|
| 232 |
+
func (_CounterAndBlock *CounterAndBlockCallerSession) Count() (*big.Int, error) {
|
| 233 |
+
return _CounterAndBlock.Contract.Count(&_CounterAndBlock.CallOpts)
|
| 234 |
+
}
|
| 235 |
+
|
| 236 |
+
// GetCount is a free data retrieval call binding the contract method 0xa87d942c.
|
| 237 |
+
//
|
| 238 |
+
// Solidity: function getCount() view returns(uint256, uint256)
|
| 239 |
+
func (_CounterAndBlock *CounterAndBlockCaller) GetCount(opts *bind.CallOpts) (*big.Int, *big.Int, error) {
|
| 240 |
+
var out []interface{}
|
| 241 |
+
err := _CounterAndBlock.contract.Call(opts, &out, "getCount")
|
| 242 |
+
|
| 243 |
+
if err != nil {
|
| 244 |
+
return *new(*big.Int), *new(*big.Int), err
|
| 245 |
+
}
|
| 246 |
+
|
| 247 |
+
out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
|
| 248 |
+
out1 := *abi.ConvertType(out[1], new(*big.Int)).(**big.Int)
|
| 249 |
+
|
| 250 |
+
return out0, out1, err
|
| 251 |
+
|
| 252 |
+
}
|
| 253 |
+
|
| 254 |
+
// GetCount is a free data retrieval call binding the contract method 0xa87d942c.
|
| 255 |
+
//
|
| 256 |
+
// Solidity: function getCount() view returns(uint256, uint256)
|
| 257 |
+
func (_CounterAndBlock *CounterAndBlockSession) GetCount() (*big.Int, *big.Int, error) {
|
| 258 |
+
return _CounterAndBlock.Contract.GetCount(&_CounterAndBlock.CallOpts)
|
| 259 |
+
}
|
| 260 |
+
|
| 261 |
+
// GetCount is a free data retrieval call binding the contract method 0xa87d942c.
|
| 262 |
+
//
|
| 263 |
+
// Solidity: function getCount() view returns(uint256, uint256)
|
| 264 |
+
func (_CounterAndBlock *CounterAndBlockCallerSession) GetCount() (*big.Int, *big.Int, error) {
|
| 265 |
+
return _CounterAndBlock.Contract.GetCount(&_CounterAndBlock.CallOpts)
|
| 266 |
+
}
|
| 267 |
+
|
| 268 |
+
// Increment is a paid mutator transaction binding the contract method 0xd09de08a.
|
| 269 |
+
//
|
| 270 |
+
// Solidity: function increment() returns()
|
| 271 |
+
func (_CounterAndBlock *CounterAndBlockTransactor) Increment(opts *bind.TransactOpts) (*types.Transaction, error) {
|
| 272 |
+
return _CounterAndBlock.contract.Transact(opts, "increment")
|
| 273 |
+
}
|
| 274 |
+
|
| 275 |
+
// Increment is a paid mutator transaction binding the contract method 0xd09de08a.
|
| 276 |
+
//
|
| 277 |
+
// Solidity: function increment() returns()
|
| 278 |
+
func (_CounterAndBlock *CounterAndBlockSession) Increment() (*types.Transaction, error) {
|
| 279 |
+
return _CounterAndBlock.Contract.Increment(&_CounterAndBlock.TransactOpts)
|
| 280 |
+
}
|
| 281 |
+
|
| 282 |
+
// Increment is a paid mutator transaction binding the contract method 0xd09de08a.
|
| 283 |
+
//
|
| 284 |
+
// Solidity: function increment() returns()
|
| 285 |
+
func (_CounterAndBlock *CounterAndBlockTransactorSession) Increment() (*types.Transaction, error) {
|
| 286 |
+
return _CounterAndBlock.Contract.Increment(&_CounterAndBlock.TransactOpts)
|
| 287 |
+
}
|
|
@@ -0,0 +1,224 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Code generated - DO NOT EDIT.
|
| 2 |
+
// This file is a generated binding and any manual changes will be lost.
|
| 3 |
+
|
| 4 |
+
package customModExp
|
| 5 |
+
|
| 6 |
+
import (
|
| 7 |
+
"errors"
|
| 8 |
+
"math/big"
|
| 9 |
+
"strings"
|
| 10 |
+
|
| 11 |
+
ethereum "github.com/ethereum/go-ethereum"
|
| 12 |
+
"github.com/ethereum/go-ethereum/accounts/abi"
|
| 13 |
+
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
| 14 |
+
"github.com/ethereum/go-ethereum/common"
|
| 15 |
+
"github.com/ethereum/go-ethereum/core/types"
|
| 16 |
+
"github.com/ethereum/go-ethereum/event"
|
| 17 |
+
)
|
| 18 |
+
|
| 19 |
+
// Reference imports to suppress errors if they are not otherwise used.
|
| 20 |
+
var (
|
| 21 |
+
_ = errors.New
|
| 22 |
+
_ = big.NewInt
|
| 23 |
+
_ = strings.NewReader
|
| 24 |
+
_ = ethereum.NotFound
|
| 25 |
+
_ = bind.Bind
|
| 26 |
+
_ = common.Big1
|
| 27 |
+
_ = types.BloomLookup
|
| 28 |
+
_ = event.NewSubscription
|
| 29 |
+
_ = abi.ConvertType
|
| 30 |
+
)
|
| 31 |
+
|
| 32 |
+
// CustomModExpMetaData contains all meta data concerning the CustomModExp contract.
|
| 33 |
+
var CustomModExpMetaData = &bind.MetaData{
|
| 34 |
+
ABI: "[{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"input\",\"type\":\"bytes\"}],\"name\":\"modExpGeneric\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
|
| 35 |
+
Bin: "0x608060405234801561001057600080fd5b50610208806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063d5665d6f14610030575b600080fd5b61004361003e3660046100e2565b610045565b005b61004d6100ad565b6101408183516020850160055afa60009081555b600a8110156100a8578181600a811061007c5761007c610193565b6020020151600482600a811061009457610094610193565b0155806100a0816101a9565b915050610061565b505050565b604051806101400160405280600a906020820280368337509192915050565b634e487b7160e01b600052604160045260246000fd5b6000602082840312156100f457600080fd5b813567ffffffffffffffff8082111561010c57600080fd5b818401915084601f83011261012057600080fd5b813581811115610132576101326100cc565b604051601f8201601f19908116603f0116810190838211818310171561015a5761015a6100cc565b8160405282815287602084870101111561017357600080fd5b826020860160208301376000928101602001929092525095945050505050565b634e487b7160e01b600052603260045260246000fd5b60006000198214156101cb57634e487b7160e01b600052601160045260246000fd5b506001019056fea26469706673582212206c4940b4c9a7086754420734c8b4921cdb547ec8b31fc3bf8cd884ad9778a5b364736f6c634300080c0033",
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
// CustomModExpABI is the input ABI used to generate the binding from.
|
| 39 |
+
// Deprecated: Use CustomModExpMetaData.ABI instead.
|
| 40 |
+
var CustomModExpABI = CustomModExpMetaData.ABI
|
| 41 |
+
|
| 42 |
+
// CustomModExpBin is the compiled bytecode used for deploying new contracts.
|
| 43 |
+
// Deprecated: Use CustomModExpMetaData.Bin instead.
|
| 44 |
+
var CustomModExpBin = CustomModExpMetaData.Bin
|
| 45 |
+
|
| 46 |
+
// DeployCustomModExp deploys a new Ethereum contract, binding an instance of CustomModExp to it.
|
| 47 |
+
func DeployCustomModExp(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *CustomModExp, error) {
|
| 48 |
+
parsed, err := CustomModExpMetaData.GetAbi()
|
| 49 |
+
if err != nil {
|
| 50 |
+
return common.Address{}, nil, nil, err
|
| 51 |
+
}
|
| 52 |
+
if parsed == nil {
|
| 53 |
+
return common.Address{}, nil, nil, errors.New("GetABI returned nil")
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(CustomModExpBin), backend)
|
| 57 |
+
if err != nil {
|
| 58 |
+
return common.Address{}, nil, nil, err
|
| 59 |
+
}
|
| 60 |
+
return address, tx, &CustomModExp{CustomModExpCaller: CustomModExpCaller{contract: contract}, CustomModExpTransactor: CustomModExpTransactor{contract: contract}, CustomModExpFilterer: CustomModExpFilterer{contract: contract}}, nil
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
// CustomModExp is an auto generated Go binding around an Ethereum contract.
|
| 64 |
+
type CustomModExp struct {
|
| 65 |
+
CustomModExpCaller // Read-only binding to the contract
|
| 66 |
+
CustomModExpTransactor // Write-only binding to the contract
|
| 67 |
+
CustomModExpFilterer // Log filterer for contract events
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
// CustomModExpCaller is an auto generated read-only Go binding around an Ethereum contract.
|
| 71 |
+
type CustomModExpCaller struct {
|
| 72 |
+
contract *bind.BoundContract // Generic contract wrapper for the low level calls
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
// CustomModExpTransactor is an auto generated write-only Go binding around an Ethereum contract.
|
| 76 |
+
type CustomModExpTransactor struct {
|
| 77 |
+
contract *bind.BoundContract // Generic contract wrapper for the low level calls
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
// CustomModExpFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
|
| 81 |
+
type CustomModExpFilterer struct {
|
| 82 |
+
contract *bind.BoundContract // Generic contract wrapper for the low level calls
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
// CustomModExpSession is an auto generated Go binding around an Ethereum contract,
|
| 86 |
+
// with pre-set call and transact options.
|
| 87 |
+
type CustomModExpSession struct {
|
| 88 |
+
Contract *CustomModExp // Generic contract binding to set the session for
|
| 89 |
+
CallOpts bind.CallOpts // Call options to use throughout this session
|
| 90 |
+
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
// CustomModExpCallerSession is an auto generated read-only Go binding around an Ethereum contract,
|
| 94 |
+
// with pre-set call options.
|
| 95 |
+
type CustomModExpCallerSession struct {
|
| 96 |
+
Contract *CustomModExpCaller // Generic contract caller binding to set the session for
|
| 97 |
+
CallOpts bind.CallOpts // Call options to use throughout this session
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
// CustomModExpTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
|
| 101 |
+
// with pre-set transact options.
|
| 102 |
+
type CustomModExpTransactorSession struct {
|
| 103 |
+
Contract *CustomModExpTransactor // Generic contract transactor binding to set the session for
|
| 104 |
+
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
|
| 105 |
+
}
|
| 106 |
+
|
| 107 |
+
// CustomModExpRaw is an auto generated low-level Go binding around an Ethereum contract.
|
| 108 |
+
type CustomModExpRaw struct {
|
| 109 |
+
Contract *CustomModExp // Generic contract binding to access the raw methods on
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
// CustomModExpCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
|
| 113 |
+
type CustomModExpCallerRaw struct {
|
| 114 |
+
Contract *CustomModExpCaller // Generic read-only contract binding to access the raw methods on
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
// CustomModExpTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
|
| 118 |
+
type CustomModExpTransactorRaw struct {
|
| 119 |
+
Contract *CustomModExpTransactor // Generic write-only contract binding to access the raw methods on
|
| 120 |
+
}
|
| 121 |
+
|
| 122 |
+
// NewCustomModExp creates a new instance of CustomModExp, bound to a specific deployed contract.
|
| 123 |
+
func NewCustomModExp(address common.Address, backend bind.ContractBackend) (*CustomModExp, error) {
|
| 124 |
+
contract, err := bindCustomModExp(address, backend, backend, backend)
|
| 125 |
+
if err != nil {
|
| 126 |
+
return nil, err
|
| 127 |
+
}
|
| 128 |
+
return &CustomModExp{CustomModExpCaller: CustomModExpCaller{contract: contract}, CustomModExpTransactor: CustomModExpTransactor{contract: contract}, CustomModExpFilterer: CustomModExpFilterer{contract: contract}}, nil
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
// NewCustomModExpCaller creates a new read-only instance of CustomModExp, bound to a specific deployed contract.
|
| 132 |
+
func NewCustomModExpCaller(address common.Address, caller bind.ContractCaller) (*CustomModExpCaller, error) {
|
| 133 |
+
contract, err := bindCustomModExp(address, caller, nil, nil)
|
| 134 |
+
if err != nil {
|
| 135 |
+
return nil, err
|
| 136 |
+
}
|
| 137 |
+
return &CustomModExpCaller{contract: contract}, nil
|
| 138 |
+
}
|
| 139 |
+
|
| 140 |
+
// NewCustomModExpTransactor creates a new write-only instance of CustomModExp, bound to a specific deployed contract.
|
| 141 |
+
func NewCustomModExpTransactor(address common.Address, transactor bind.ContractTransactor) (*CustomModExpTransactor, error) {
|
| 142 |
+
contract, err := bindCustomModExp(address, nil, transactor, nil)
|
| 143 |
+
if err != nil {
|
| 144 |
+
return nil, err
|
| 145 |
+
}
|
| 146 |
+
return &CustomModExpTransactor{contract: contract}, nil
|
| 147 |
+
}
|
| 148 |
+
|
| 149 |
+
// NewCustomModExpFilterer creates a new log filterer instance of CustomModExp, bound to a specific deployed contract.
|
| 150 |
+
func NewCustomModExpFilterer(address common.Address, filterer bind.ContractFilterer) (*CustomModExpFilterer, error) {
|
| 151 |
+
contract, err := bindCustomModExp(address, nil, nil, filterer)
|
| 152 |
+
if err != nil {
|
| 153 |
+
return nil, err
|
| 154 |
+
}
|
| 155 |
+
return &CustomModExpFilterer{contract: contract}, nil
|
| 156 |
+
}
|
| 157 |
+
|
| 158 |
+
// bindCustomModExp binds a generic wrapper to an already deployed contract.
|
| 159 |
+
func bindCustomModExp(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
|
| 160 |
+
parsed, err := CustomModExpMetaData.GetAbi()
|
| 161 |
+
if err != nil {
|
| 162 |
+
return nil, err
|
| 163 |
+
}
|
| 164 |
+
return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
|
| 165 |
+
}
|
| 166 |
+
|
| 167 |
+
// Call invokes the (constant) contract method with params as input values and
|
| 168 |
+
// sets the output to result. The result type might be a single field for simple
|
| 169 |
+
// returns, a slice of interfaces for anonymous returns and a struct for named
|
| 170 |
+
// returns.
|
| 171 |
+
func (_CustomModExp *CustomModExpRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
|
| 172 |
+
return _CustomModExp.Contract.CustomModExpCaller.contract.Call(opts, result, method, params...)
|
| 173 |
+
}
|
| 174 |
+
|
| 175 |
+
// Transfer initiates a plain transaction to move funds to the contract, calling
|
| 176 |
+
// its default method if one is available.
|
| 177 |
+
func (_CustomModExp *CustomModExpRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
|
| 178 |
+
return _CustomModExp.Contract.CustomModExpTransactor.contract.Transfer(opts)
|
| 179 |
+
}
|
| 180 |
+
|
| 181 |
+
// Transact invokes the (paid) contract method with params as input values.
|
| 182 |
+
func (_CustomModExp *CustomModExpRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
|
| 183 |
+
return _CustomModExp.Contract.CustomModExpTransactor.contract.Transact(opts, method, params...)
|
| 184 |
+
}
|
| 185 |
+
|
| 186 |
+
// Call invokes the (constant) contract method with params as input values and
|
| 187 |
+
// sets the output to result. The result type might be a single field for simple
|
| 188 |
+
// returns, a slice of interfaces for anonymous returns and a struct for named
|
| 189 |
+
// returns.
|
| 190 |
+
func (_CustomModExp *CustomModExpCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
|
| 191 |
+
return _CustomModExp.Contract.contract.Call(opts, result, method, params...)
|
| 192 |
+
}
|
| 193 |
+
|
| 194 |
+
// Transfer initiates a plain transaction to move funds to the contract, calling
|
| 195 |
+
// its default method if one is available.
|
| 196 |
+
func (_CustomModExp *CustomModExpTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
|
| 197 |
+
return _CustomModExp.Contract.contract.Transfer(opts)
|
| 198 |
+
}
|
| 199 |
+
|
| 200 |
+
// Transact invokes the (paid) contract method with params as input values.
|
| 201 |
+
func (_CustomModExp *CustomModExpTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
|
| 202 |
+
return _CustomModExp.Contract.contract.Transact(opts, method, params...)
|
| 203 |
+
}
|
| 204 |
+
|
| 205 |
+
// ModExpGeneric is a paid mutator transaction binding the contract method 0xd5665d6f.
|
| 206 |
+
//
|
| 207 |
+
// Solidity: function modExpGeneric(bytes input) returns()
|
| 208 |
+
func (_CustomModExp *CustomModExpTransactor) ModExpGeneric(opts *bind.TransactOpts, input []byte) (*types.Transaction, error) {
|
| 209 |
+
return _CustomModExp.contract.Transact(opts, "modExpGeneric", input)
|
| 210 |
+
}
|
| 211 |
+
|
| 212 |
+
// ModExpGeneric is a paid mutator transaction binding the contract method 0xd5665d6f.
|
| 213 |
+
//
|
| 214 |
+
// Solidity: function modExpGeneric(bytes input) returns()
|
| 215 |
+
func (_CustomModExp *CustomModExpSession) ModExpGeneric(input []byte) (*types.Transaction, error) {
|
| 216 |
+
return _CustomModExp.Contract.ModExpGeneric(&_CustomModExp.TransactOpts, input)
|
| 217 |
+
}
|
| 218 |
+
|
| 219 |
+
// ModExpGeneric is a paid mutator transaction binding the contract method 0xd5665d6f.
|
| 220 |
+
//
|
| 221 |
+
// Solidity: function modExpGeneric(bytes input) returns()
|
| 222 |
+
func (_CustomModExp *CustomModExpTransactorSession) ModExpGeneric(input []byte) (*types.Transaction, error) {
|
| 223 |
+
return _CustomModExp.Contract.ModExpGeneric(&_CustomModExp.TransactOpts, input)
|
| 224 |
+
}
|
|
@@ -32,7 +32,7 @@
|
|
| 32 |
// TriggerErrorsMetaData contains all meta data concerning the TriggerErrors contract.
|
| 33 |
var TriggerErrorsMetaData = &bind.MetaData{
|
| 34 |
ABI: "[{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"outOfCountersKeccaks\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"test\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"outOfCountersPoseidon\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"outOfCountersSteps\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"outOfGas\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
|
| 35 |
-
Bin: "
|
| 36 |
}
|
| 37 |
|
| 38 |
// TriggerErrorsABI is the input ABI used to generate the binding from.
|
|
|
|
| 32 |
// TriggerErrorsMetaData contains all meta data concerning the TriggerErrors contract.
|
| 33 |
var TriggerErrorsMetaData = &bind.MetaData{
|
| 34 |
ABI: "[{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"outOfCountersKeccaks\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"test\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"outOfCountersPoseidon\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"outOfCountersSteps\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"outOfGas\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
|
| 35 |
+
Bin: "0x60806040526000805534801561001457600080fd5b5061016c806100246000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c806306661abd1461005c5780632621002a1461007757806331fe52e8146100835780638bd7b5381461008d578063cb4e8cd114610095575b600080fd5b61006560005481565b60405190815260200160405180910390f35b620f4240600020610065565b61008b61009d565b005b61008b6100c3565b61008b6100e9565b60005b60648110156100c0578060005580806100b89061010d565b9150506100a0565b50565b60005b620186a08110156100c0576104d2600052806100e18161010d565b9150506100c6565b60005b61c3508110156100c0578060005580806101059061010d565b9150506100ec565b600060001982141561012f57634e487b7160e01b600052601160045260246000fd5b506001019056fea26469706673582212208f01c5dc055b1f376f5da5deb33e2c96ee776174bf48874c5ebba0f606de2ac564736f6c634300080c0033",
|
| 36 |
}
|
| 37 |
|
| 38 |
// TriggerErrorsABI is the input ABI used to generate the binding from.
|
|
@@ -2,7 +2,7 @@
|
|
| 2 |
networks:
|
| 3 |
default:
|
| 4 |
name: zkevm
|
| 5 |
-
|
| 6 |
services:
|
| 7 |
grafana:
|
| 8 |
container_name: grafana
|
|
@@ -453,7 +453,7 @@
|
|
| 453 |
|
| 454 |
zkevm-mock-l1-network:
|
| 455 |
container_name: zkevm-mock-l1-network
|
| 456 |
-
image:
|
| 457 |
ports:
|
| 458 |
- 8545:8545
|
| 459 |
- 8546:8546
|
|
@@ -519,6 +519,8 @@
|
|
| 519 |
- 50071:50071 # Executor
|
| 520 |
volumes:
|
| 521 |
- ./config/test.prover.config.json:/usr/src/app/config.json
|
|
|
|
|
|
|
| 522 |
command: >
|
| 523 |
zkProver -c /usr/src/app/config.json
|
| 524 |
|
|
@@ -610,6 +612,8 @@
|
|
| 610 |
- 50078:50071 # Executor
|
| 611 |
volumes:
|
| 612 |
- ./config/test.permissionless.prover.config.json:/usr/src/app/config.json
|
|
|
|
|
|
|
| 613 |
command: >
|
| 614 |
zkProver -c /usr/src/app/config.json
|
| 615 |
|
|
@@ -628,7 +632,7 @@
|
|
| 628 |
zkevm-sh:
|
| 629 |
container_name: zkevm-sh
|
| 630 |
image: zkevm-node
|
| 631 |
-
stdin_open: true
|
| 632 |
tty: true
|
| 633 |
environment:
|
| 634 |
- ZKEVM_NODE_STATE_DB_HOST=zkevm-state-db
|
|
@@ -638,3 +642,51 @@
|
|
| 638 |
- ./config/test.genesis.config.json:/app/genesis.json
|
| 639 |
command:
|
| 640 |
- "/bin/sh"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
networks:
|
| 3 |
default:
|
| 4 |
name: zkevm
|
| 5 |
+
|
| 6 |
services:
|
| 7 |
grafana:
|
| 8 |
container_name: grafana
|
|
|
|
| 453 |
|
| 454 |
zkevm-mock-l1-network:
|
| 455 |
container_name: zkevm-mock-l1-network
|
| 456 |
+
image: 0xpolygon/cdk-validium-contracts:forkId8
|
| 457 |
ports:
|
| 458 |
- 8545:8545
|
| 459 |
- 8546:8546
|
|
|
|
| 519 |
- 50071:50071 # Executor
|
| 520 |
volumes:
|
| 521 |
- ./config/test.prover.config.json:/usr/src/app/config.json
|
| 522 |
+
environment:
|
| 523 |
+
- EXPERIMENTAL_DOCKER_DESKTOP_FORCE_QEMU=1
|
| 524 |
command: >
|
| 525 |
zkProver -c /usr/src/app/config.json
|
| 526 |
|
|
|
|
| 612 |
- 50078:50071 # Executor
|
| 613 |
volumes:
|
| 614 |
- ./config/test.permissionless.prover.config.json:/usr/src/app/config.json
|
| 615 |
+
environment:
|
| 616 |
+
- EXPERIMENTAL_DOCKER_DESKTOP_FORCE_QEMU=1
|
| 617 |
command: >
|
| 618 |
zkProver -c /usr/src/app/config.json
|
| 619 |
|
|
|
|
| 632 |
zkevm-sh:
|
| 633 |
container_name: zkevm-sh
|
| 634 |
image: zkevm-node
|
| 635 |
+
stdin_open: true
|
| 636 |
tty: true
|
| 637 |
environment:
|
| 638 |
- ZKEVM_NODE_STATE_DB_HOST=zkevm-state-db
|
|
|
|
| 642 |
- ./config/test.genesis.config.json:/app/genesis.json
|
| 643 |
command:
|
| 644 |
- "/bin/sh"
|
| 645 |
+
|
| 646 |
+
zkevm-node-forced-DAC:
|
| 647 |
+
container_name: zkevm-node-forced-DAC
|
| 648 |
+
image: zkevm-node
|
| 649 |
+
ports:
|
| 650 |
+
- 8125:8125
|
| 651 |
+
environment:
|
| 652 |
+
- ZKEVM_NODE_ISTRUSTEDSEQUENCER=false
|
| 653 |
+
- ZKEVM_NODE_STATEDB_USER=test_user
|
| 654 |
+
- ZKEVM_NODE_STATEDB_PASSWORD=test_password
|
| 655 |
+
- ZKEVM_NODE_STATEDB_NAME=state_db
|
| 656 |
+
- ZKEVM_NODE_STATEDB_HOST=zkevm-permissionless-db
|
| 657 |
+
- ZKEVM_NODE_POOL_DB_USER=test_user
|
| 658 |
+
- ZKEVM_NODE_POOL_DB_PASSWORD=test_password
|
| 659 |
+
- ZKEVM_NODE_POOL_DB_NAME=pool_db
|
| 660 |
+
- ZKEVM_NODE_POOL_DB_HOST=zkevm-permissionless-db
|
| 661 |
+
- ZKEVM_NODE_RPC_PORT=8125
|
| 662 |
+
- ZKEVM_NODE_RPC_SEQUENCERNODEURI=http://zkevm-node-json-rpc:8123
|
| 663 |
+
- ZKEVM_NODE_SYNCHRONIZER_TRUSTEDSEQUENCERURL=http://you-cant-touch-this:8123
|
| 664 |
+
- ZKEVM_NODE_MTCLIENT_URI=zkevm-permissionless-prover:50061
|
| 665 |
+
- ZKEVM_NODE_EXECUTOR_URI=zkevm-permissionless-prover:50071
|
| 666 |
+
volumes:
|
| 667 |
+
- ./config/test.node.config.toml:/app/config.toml
|
| 668 |
+
- ./config/test.genesis.config.json:/app/genesis.json
|
| 669 |
+
command:
|
| 670 |
+
- "/bin/sh"
|
| 671 |
+
- "-c"
|
| 672 |
+
- "/app/zkevm-node run --network custom --custom-network-file /app/genesis.json --cfg /app/config.toml --components \"rpc,synchronizer\""
|
| 673 |
+
|
| 674 |
+
zkevm-data-node-db:
|
| 675 |
+
container_name: zkevm-data-node-db
|
| 676 |
+
restart: unless-stopped
|
| 677 |
+
image: postgres
|
| 678 |
+
healthcheck:
|
| 679 |
+
test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
|
| 680 |
+
interval: 10s
|
| 681 |
+
timeout: 5s
|
| 682 |
+
retries: 5
|
| 683 |
+
ports:
|
| 684 |
+
- 5444:5432
|
| 685 |
+
environment:
|
| 686 |
+
- POSTGRES_USER=committee_user
|
| 687 |
+
- POSTGRES_PASSWORD=committee_password
|
| 688 |
+
- POSTGRES_DB=committee_db
|
| 689 |
+
command:
|
| 690 |
+
- "postgres"
|
| 691 |
+
- "-N"
|
| 692 |
+
- "500"
|
|
@@ -0,0 +1,270 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package e2e
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"context"
|
| 5 |
+
"crypto/ecdsa"
|
| 6 |
+
"encoding/json"
|
| 7 |
+
"fmt"
|
| 8 |
+
"math/big"
|
| 9 |
+
"os"
|
| 10 |
+
"os/exec"
|
| 11 |
+
"sort"
|
| 12 |
+
"strconv"
|
| 13 |
+
"strings"
|
| 14 |
+
"testing"
|
| 15 |
+
"time"
|
| 16 |
+
|
| 17 |
+
"github.com/0xPolygon/cdk-data-availability/config"
|
| 18 |
+
cTypes "github.com/0xPolygon/cdk-data-availability/config/types"
|
| 19 |
+
"github.com/0xPolygon/cdk-data-availability/db"
|
| 20 |
+
"github.com/0xPolygon/cdk-data-availability/rpc"
|
| 21 |
+
"github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/polygondatacommittee"
|
| 22 |
+
"github.com/0xPolygonHermez/zkevm-node/log"
|
| 23 |
+
"github.com/0xPolygonHermez/zkevm-node/test/operations"
|
| 24 |
+
"github.com/ethereum/go-ethereum"
|
| 25 |
+
eTypes "github.com/ethereum/go-ethereum/core/types"
|
| 26 |
+
|
| 27 |
+
"github.com/ethereum/go-ethereum/accounts/keystore"
|
| 28 |
+
"github.com/ethereum/go-ethereum/common"
|
| 29 |
+
"github.com/ethereum/go-ethereum/crypto"
|
| 30 |
+
"github.com/ethereum/go-ethereum/ethclient"
|
| 31 |
+
"github.com/stretchr/testify/assert"
|
| 32 |
+
"github.com/stretchr/testify/require"
|
| 33 |
+
)
|
| 34 |
+
|
| 35 |
+
func TestDataCommittee(t *testing.T) {
|
| 36 |
+
const (
|
| 37 |
+
nSignatures = 4
|
| 38 |
+
mMembers = 5
|
| 39 |
+
ksFile = "/tmp/pkey"
|
| 40 |
+
cfgFile = "/tmp/dacnodeconfigfile.json"
|
| 41 |
+
ksPass = "pass"
|
| 42 |
+
dacNodeContainer = "hermeznetwork/cdk-data-availability:v0.0.4"
|
| 43 |
+
)
|
| 44 |
+
|
| 45 |
+
// Setup
|
| 46 |
+
var err error
|
| 47 |
+
if testing.Short() {
|
| 48 |
+
t.Skip()
|
| 49 |
+
}
|
| 50 |
+
ctx := context.Background()
|
| 51 |
+
defer func() {
|
| 52 |
+
require.NoError(t, operations.Teardown())
|
| 53 |
+
}()
|
| 54 |
+
err = operations.Teardown()
|
| 55 |
+
require.NoError(t, err)
|
| 56 |
+
opsCfg := operations.GetDefaultOperationsConfig()
|
| 57 |
+
opsCfg.State.MaxCumulativeGasUsed = 80000000000
|
| 58 |
+
opsman, err := operations.NewManager(ctx, opsCfg)
|
| 59 |
+
require.NoError(t, err)
|
| 60 |
+
defer func() {
|
| 61 |
+
require.NoError(t, opsman.StopDACDB())
|
| 62 |
+
}()
|
| 63 |
+
err = opsman.Setup()
|
| 64 |
+
require.NoError(t, err)
|
| 65 |
+
require.NoError(t, opsman.StartDACDB())
|
| 66 |
+
time.Sleep(5 * time.Second)
|
| 67 |
+
authL2, err := operations.GetAuth(operations.DefaultSequencerPrivateKey, operations.DefaultL2ChainID)
|
| 68 |
+
require.NoError(t, err)
|
| 69 |
+
authL1, err := operations.GetAuth(operations.DefaultSequencerPrivateKey, operations.DefaultL1ChainID)
|
| 70 |
+
require.NoError(t, err)
|
| 71 |
+
clientL2, err := ethclient.Dial(operations.DefaultL2NetworkURL)
|
| 72 |
+
require.NoError(t, err)
|
| 73 |
+
clientL1, err := ethclient.Dial(operations.DefaultL1NetworkURL)
|
| 74 |
+
require.NoError(t, err)
|
| 75 |
+
dacSC, err := polygondatacommittee.NewPolygondatacommittee(
|
| 76 |
+
common.HexToAddress(operations.DefaultL1DataCommitteeContract),
|
| 77 |
+
clientL1,
|
| 78 |
+
)
|
| 79 |
+
require.NoError(t, err)
|
| 80 |
+
|
| 81 |
+
// Register committe with N / M signatures
|
| 82 |
+
membs := members{}
|
| 83 |
+
addrsBytes := []byte{}
|
| 84 |
+
urls := []string{}
|
| 85 |
+
for i := 0; i < mMembers; i++ {
|
| 86 |
+
pk, err := crypto.GenerateKey()
|
| 87 |
+
require.NoError(t, err)
|
| 88 |
+
membs = append(membs, member{
|
| 89 |
+
addr: crypto.PubkeyToAddress(pk.PublicKey),
|
| 90 |
+
pk: pk,
|
| 91 |
+
url: fmt.Sprintf("http://cdk-data-availability-%d:420%d", i, i),
|
| 92 |
+
i: i,
|
| 93 |
+
})
|
| 94 |
+
}
|
| 95 |
+
sort.Sort(membs)
|
| 96 |
+
for _, m := range membs {
|
| 97 |
+
addrsBytes = append(addrsBytes, m.addr.Bytes()...)
|
| 98 |
+
urls = append(urls, m.url)
|
| 99 |
+
}
|
| 100 |
+
tx, err := dacSC.SetupCommittee(authL1, big.NewInt(nSignatures), urls, addrsBytes)
|
| 101 |
+
for _, m := range membs {
|
| 102 |
+
fmt.Println(m.addr)
|
| 103 |
+
}
|
| 104 |
+
require.NoError(t, err)
|
| 105 |
+
err = operations.WaitTxToBeMined(ctx, clientL1, tx, operations.DefaultTimeoutTxToBeMined)
|
| 106 |
+
require.NoError(t, err)
|
| 107 |
+
|
| 108 |
+
// Spin up M DAC nodes
|
| 109 |
+
dacNodeConfig := config.Config{
|
| 110 |
+
L1: config.L1Config{
|
| 111 |
+
RpcURL: "http://zkevm-mock-l1-network:8545",
|
| 112 |
+
WsURL: "ws://zkevm-mock-l1-network:8546",
|
| 113 |
+
PolygonValidiumAddress: operations.DefaultL1ZkEVMSmartContract,
|
| 114 |
+
DataCommitteeAddress: operations.DefaultL1DataCommitteeContract,
|
| 115 |
+
Timeout: cTypes.Duration{Duration: time.Second},
|
| 116 |
+
RetryPeriod: cTypes.Duration{Duration: time.Second},
|
| 117 |
+
},
|
| 118 |
+
PrivateKey: cTypes.KeystoreFileConfig{
|
| 119 |
+
Path: ksFile,
|
| 120 |
+
Password: ksPass,
|
| 121 |
+
},
|
| 122 |
+
DB: db.Config{
|
| 123 |
+
Name: "committee_db",
|
| 124 |
+
User: "committee_user",
|
| 125 |
+
Password: "committee_password",
|
| 126 |
+
Host: "zkevm-data-node-db",
|
| 127 |
+
Port: "5432",
|
| 128 |
+
EnableLog: false,
|
| 129 |
+
MaxConns: 10,
|
| 130 |
+
},
|
| 131 |
+
RPC: rpc.Config{
|
| 132 |
+
Host: "0.0.0.0",
|
| 133 |
+
MaxRequestsPerIPAndSecond: 100,
|
| 134 |
+
},
|
| 135 |
+
}
|
| 136 |
+
defer func() {
|
| 137 |
+
// Remove tmp files
|
| 138 |
+
assert.NoError(t,
|
| 139 |
+
exec.Command("rm", cfgFile).Run(),
|
| 140 |
+
)
|
| 141 |
+
assert.NoError(t,
|
| 142 |
+
exec.Command("rmdir", ksFile+"_").Run(),
|
| 143 |
+
)
|
| 144 |
+
assert.NoError(t,
|
| 145 |
+
exec.Command("rm", ksFile).Run(),
|
| 146 |
+
)
|
| 147 |
+
// Stop DAC nodes
|
| 148 |
+
for i := 0; i < mMembers; i++ {
|
| 149 |
+
assert.NoError(t, exec.Command(
|
| 150 |
+
"docker", "kill", "cdk-data-availability-"+strconv.Itoa(i),
|
| 151 |
+
).Run())
|
| 152 |
+
assert.NoError(t, exec.Command(
|
| 153 |
+
"docker", "rm", "cdk-data-availability-"+strconv.Itoa(i),
|
| 154 |
+
).Run())
|
| 155 |
+
}
|
| 156 |
+
// Stop permissionless node
|
| 157 |
+
require.NoError(t, opsman.StopPermissionlessNodeForcedToSYncThroughDAC())
|
| 158 |
+
}()
|
| 159 |
+
// Start permissionless node
|
| 160 |
+
require.NoError(t, opsman.StartPermissionlessNodeForcedToSYncThroughDAC())
|
| 161 |
+
// Star DAC nodes
|
| 162 |
+
for _, m := range membs {
|
| 163 |
+
// Set correct port
|
| 164 |
+
port := 4200 + m.i
|
| 165 |
+
dacNodeConfig.RPC.Port = port
|
| 166 |
+
// Write config file
|
| 167 |
+
file, err := json.MarshalIndent(dacNodeConfig, "", " ")
|
| 168 |
+
require.NoError(t, err)
|
| 169 |
+
err = os.WriteFile(cfgFile, file, 0644)
|
| 170 |
+
require.NoError(t, err)
|
| 171 |
+
// Write private key keystore file
|
| 172 |
+
err = createKeyStore(m.pk, ksFile, ksPass)
|
| 173 |
+
require.NoError(t, err)
|
| 174 |
+
// Run DAC node
|
| 175 |
+
cmd := exec.Command(
|
| 176 |
+
"docker", "run", "-d",
|
| 177 |
+
"--name", "cdk-data-availability-"+strconv.Itoa(m.i),
|
| 178 |
+
"-v", cfgFile+":/app/config.json",
|
| 179 |
+
"-v", ksFile+":"+ksFile,
|
| 180 |
+
"--network", "zkevm",
|
| 181 |
+
dacNodeContainer,
|
| 182 |
+
"/bin/sh", "-c",
|
| 183 |
+
"/app/cdk-data-availability run --cfg /app/config.json",
|
| 184 |
+
)
|
| 185 |
+
out, err := cmd.CombinedOutput()
|
| 186 |
+
require.NoError(t, err, string(out))
|
| 187 |
+
log.Infof("DAC node %d started", m.i)
|
| 188 |
+
time.Sleep(time.Second * 5)
|
| 189 |
+
}
|
| 190 |
+
|
| 191 |
+
// Send txs
|
| 192 |
+
nTxs := 10
|
| 193 |
+
amount := big.NewInt(10000)
|
| 194 |
+
toAddress := common.HexToAddress("0x70997970C51812dc3A010C7d01b50e0d17dc79C8")
|
| 195 |
+
_, err = clientL2.BalanceAt(ctx, authL2.From, nil)
|
| 196 |
+
require.NoError(t, err)
|
| 197 |
+
_, err = clientL2.PendingNonceAt(ctx, authL2.From)
|
| 198 |
+
require.NoError(t, err)
|
| 199 |
+
|
| 200 |
+
gasLimit, err := clientL2.EstimateGas(ctx, ethereum.CallMsg{From: authL2.From, To: &toAddress, Value: amount})
|
| 201 |
+
require.NoError(t, err)
|
| 202 |
+
|
| 203 |
+
gasPrice, err := clientL2.SuggestGasPrice(ctx)
|
| 204 |
+
require.NoError(t, err)
|
| 205 |
+
|
| 206 |
+
nonce, err := clientL2.PendingNonceAt(ctx, authL2.From)
|
| 207 |
+
require.NoError(t, err)
|
| 208 |
+
|
| 209 |
+
txs := make([]*eTypes.Transaction, 0, nTxs)
|
| 210 |
+
for i := 0; i < nTxs; i++ {
|
| 211 |
+
tx := eTypes.NewTransaction(nonce+uint64(i), toAddress, amount, gasLimit, gasPrice, nil)
|
| 212 |
+
log.Infof("generating tx %d / %d: %s", i+1, nTxs, tx.Hash().Hex())
|
| 213 |
+
txs = append(txs, tx)
|
| 214 |
+
}
|
| 215 |
+
|
| 216 |
+
// Wait for verification
|
| 217 |
+
_, err = operations.ApplyL2Txs(ctx, txs, authL2, clientL2, operations.VerifiedConfirmationLevel)
|
| 218 |
+
require.NoError(t, err)
|
| 219 |
+
|
| 220 |
+
// Assert that he permissionless node is fully synced (through the DAC)
|
| 221 |
+
time.Sleep(30 * time.Second) // Give some time for the permissionless node to get synced
|
| 222 |
+
clientL2Permissionless, err := ethclient.Dial(operations.PermissionlessL2NetworkURL)
|
| 223 |
+
require.NoError(t, err)
|
| 224 |
+
expectedBlock, err := clientL2.BlockByNumber(ctx, nil)
|
| 225 |
+
require.NoError(t, err)
|
| 226 |
+
actualBlock, err := clientL2Permissionless.BlockByNumber(ctx, nil)
|
| 227 |
+
require.NoError(t, err)
|
| 228 |
+
// je, err := expectedBlock.Header().MarshalJSON()
|
| 229 |
+
// require.NoError(t, err)
|
| 230 |
+
// log.Info(string(je))
|
| 231 |
+
// ja, err := actualBlock.Header().MarshalJSON()
|
| 232 |
+
// require.NoError(t, err)
|
| 233 |
+
// log.Info(string(ja))
|
| 234 |
+
// require.Equal(t, string(je), string(ja))
|
| 235 |
+
require.Equal(t, expectedBlock.Root().Hex(), actualBlock.Root().Hex())
|
| 236 |
+
}
|
| 237 |
+
|
| 238 |
+
type member struct {
|
| 239 |
+
addr common.Address
|
| 240 |
+
pk *ecdsa.PrivateKey
|
| 241 |
+
url string
|
| 242 |
+
i int
|
| 243 |
+
}
|
| 244 |
+
type members []member
|
| 245 |
+
|
| 246 |
+
func (s members) Len() int { return len(s) }
|
| 247 |
+
func (s members) Less(i, j int) bool {
|
| 248 |
+
return strings.ToUpper(s[i].addr.Hex()) < strings.ToUpper(s[j].addr.Hex())
|
| 249 |
+
}
|
| 250 |
+
func (s members) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
| 251 |
+
|
| 252 |
+
func createKeyStore(pk *ecdsa.PrivateKey, outputDir, password string) error {
|
| 253 |
+
ks := keystore.NewKeyStore(outputDir+"_", keystore.StandardScryptN, keystore.StandardScryptP)
|
| 254 |
+
_, err := ks.ImportECDSA(pk, password)
|
| 255 |
+
if err != nil {
|
| 256 |
+
return err
|
| 257 |
+
}
|
| 258 |
+
fileNameB, err := exec.Command("ls", outputDir+"_/").CombinedOutput()
|
| 259 |
+
fileName := strings.TrimSuffix(string(fileNameB), "\n")
|
| 260 |
+
if err != nil {
|
| 261 |
+
fmt.Println(fileName)
|
| 262 |
+
return err
|
| 263 |
+
}
|
| 264 |
+
out, err := exec.Command("mv", outputDir+"_/"+fileName, outputDir).CombinedOutput()
|
| 265 |
+
if err != nil {
|
| 266 |
+
fmt.Println(string(out))
|
| 267 |
+
return err
|
| 268 |
+
}
|
| 269 |
+
return nil
|
| 270 |
+
}
|
|
@@ -196,7 +196,7 @@
|
|
| 196 |
require.NoError(t, err)
|
| 197 |
genesisConfig, err := config.LoadGenesisFromJSONString(genesisFileAsStr)
|
| 198 |
require.NoError(t, err)
|
| 199 |
-
require.NoError(t, opsman.SetForkID(genesisConfig.Genesis.
|
| 200 |
err = opsman.Setup()
|
| 201 |
require.NoError(t, err)
|
| 202 |
time.Sleep(5 * time.Second)
|
|
|
|
| 196 |
require.NoError(t, err)
|
| 197 |
genesisConfig, err := config.LoadGenesisFromJSONString(genesisFileAsStr)
|
| 198 |
require.NoError(t, err)
|
| 199 |
+
require.NoError(t, opsman.SetForkID(genesisConfig.Genesis.RollupBlockNumber, forkID6))
|
| 200 |
err = opsman.Setup()
|
| 201 |
require.NoError(t, err)
|
| 202 |
time.Sleep(5 * time.Second)
|
|
@@ -63,8 +63,8 @@
|
|
| 63 |
log.Info("# Setting Genesis #")
|
| 64 |
log.Info("###################")
|
| 65 |
genesisActions := vectors.GenerateGenesisActions(testCase.Genesis)
|
| 66 |
-
require.NoError(t, opsman.SetGenesis(genesisConfig.Genesis.
|
| 67 |
-
require.NoError(t, opsman.SetForkID(genesisConfig.Genesis.
|
| 68 |
actualOldStateRoot, err := opsman.State().GetLastStateRoot(ctx, nil)
|
| 69 |
require.NoError(t, err)
|
| 70 |
require.NoError(t, opsman.Setup())
|
|
@@ -93,7 +93,7 @@
|
|
| 93 |
}
|
| 94 |
|
| 95 |
log.Info("#######################")
|
| 96 |
-
log.Info("# Verifying new
|
| 97 |
log.Info("#######################")
|
| 98 |
merkleTree := opsman.State().GetTree()
|
| 99 |
for _, expectedNewLeaf := range testCase.ExpectedNewLeafs {
|
|
|
|
| 63 |
log.Info("# Setting Genesis #")
|
| 64 |
log.Info("###################")
|
| 65 |
genesisActions := vectors.GenerateGenesisActions(testCase.Genesis)
|
| 66 |
+
require.NoError(t, opsman.SetGenesis(genesisConfig.Genesis.RollupBlockNumber, genesisActions))
|
| 67 |
+
require.NoError(t, opsman.SetForkID(genesisConfig.Genesis.RollupBlockNumber, forkID6))
|
| 68 |
actualOldStateRoot, err := opsman.State().GetLastStateRoot(ctx, nil)
|
| 69 |
require.NoError(t, err)
|
| 70 |
require.NoError(t, opsman.Setup())
|
|
|
|
| 93 |
}
|
| 94 |
|
| 95 |
log.Info("#######################")
|
| 96 |
+
log.Info("# Verifying new leaves #")
|
| 97 |
log.Info("#######################")
|
| 98 |
merkleTree := opsman.State().GetTree()
|
| 99 |
for _, expectedNewLeaf := range testCase.ExpectedNewLeafs {
|
|
@@ -456,22 +456,27 @@
|
|
| 456 |
expectedError: types.ErrorObject{Code: types.InvalidParamsErrorCode, Message: "missing value for required argument 0"},
|
| 457 |
},
|
| 458 |
{
|
| 459 |
-
name:
|
| 460 |
-
params:
|
| 461 |
-
expectedError: types.ErrorObject{Code: types.InvalidParamsErrorCode, Message: "missing value for required argument 1"},
|
| 462 |
},
|
| 463 |
}
|
| 464 |
|
| 465 |
for _, network := range networks {
|
| 466 |
-
|
| 467 |
-
for
|
|
|
|
| 468 |
t.Run(network.Name+testCase.name, func(t *testing.T) {
|
| 469 |
response, err := client.JSONRPCCall(network.URL, "eth_call", testCase.params...)
|
| 470 |
require.NoError(t, err)
|
| 471 |
-
|
| 472 |
-
|
| 473 |
-
|
| 474 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 475 |
})
|
| 476 |
}
|
| 477 |
}
|
|
@@ -620,24 +625,39 @@
|
|
| 620 |
txToMsg, err := sc.Increment(auth)
|
| 621 |
require.NoError(t, err)
|
| 622 |
|
| 623 |
-
//
|
| 624 |
-
|
| 625 |
-
|
| 626 |
-
|
| 627 |
-
|
| 628 |
-
|
| 629 |
-
|
| 630 |
-
|
| 631 |
-
|
| 632 |
-
|
| 633 |
-
|
| 634 |
-
|
| 635 |
-
|
| 636 |
-
|
| 637 |
-
|
| 638 |
-
|
| 639 |
-
|
| 640 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 641 |
|
| 642 |
type testCase struct {
|
| 643 |
name string
|
|
@@ -670,19 +690,15 @@
|
|
| 670 |
name: "with gasPrice set and without from address",
|
| 671 |
address: nil,
|
| 672 |
setGasPrice: true,
|
| 673 |
-
expectedError:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 674 |
},
|
| 675 |
-
// TODO: This test is failing due to geth bug
|
| 676 |
-
// we can uncomment it when updating geth version
|
| 677 |
-
// on l1 image, it's returning error code -32000 when
|
| 678 |
-
// it should be returning error code 3 due to execution message
|
| 679 |
-
// {
|
| 680 |
-
// name: "with gasPrice and value set and address with enough balance",
|
| 681 |
-
// address: state.Ptr(auth.From),
|
| 682 |
-
// value: state.Ptr(int64(1)),
|
| 683 |
-
// setGasPrice: true,
|
| 684 |
-
// expectedError: types.NewRPCError(3, "execution reverted"),
|
| 685 |
-
// },
|
| 686 |
{
|
| 687 |
name: "with gasPrice and value set and address without enough balance",
|
| 688 |
address: state.Ptr(common.HexToAddress("0x1")),
|
|
@@ -697,13 +713,21 @@
|
|
| 697 |
setGasPrice: true,
|
| 698 |
expectedError: types.NewRPCError(-32000, "insufficient funds for transfer"),
|
| 699 |
},
|
| 700 |
-
|
| 701 |
-
|
| 702 |
-
|
| 703 |
-
|
| 704 |
-
|
| 705 |
-
|
| 706 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 707 |
{
|
| 708 |
name: "without gasPrice set and address with enough balance",
|
| 709 |
address: state.Ptr(auth.From),
|
|
@@ -746,7 +770,6 @@
|
|
| 746 |
if testCase.value != nil {
|
| 747 |
v := *testCase.value
|
| 748 |
if v == -1 { //set the value as acc balance + 1 to force overflow
|
| 749 |
-
|
| 750 |
msg.Value = common.Big0.Add(balance, common.Big1)
|
| 751 |
} else {
|
| 752 |
msg.Value = big.NewInt(0).SetInt64(v)
|
|
@@ -757,7 +780,10 @@
|
|
| 757 |
msg.GasPrice = gasPrice
|
| 758 |
}
|
| 759 |
|
| 760 |
-
|
|
|
|
|
|
|
|
|
|
| 761 |
if testCase.expectedError != nil {
|
| 762 |
rpcErr := err.(rpc.Error)
|
| 763 |
errMsg := fmt.Sprintf("[%v] expected: %v %v found: %v %v", network.Name, testCase.expectedError.ErrorCode(), testCase.expectedError.Error(), rpcErr.ErrorCode(), rpcErr.Error())
|
|
|
|
| 456 |
expectedError: types.ErrorObject{Code: types.InvalidParamsErrorCode, Message: "missing value for required argument 0"},
|
| 457 |
},
|
| 458 |
{
|
| 459 |
+
name: "params has only first parameter",
|
| 460 |
+
params: []interface{}{map[string]interface{}{"value": "0x1", "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", "to": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92267"}},
|
|
|
|
| 461 |
},
|
| 462 |
}
|
| 463 |
|
| 464 |
for _, network := range networks {
|
| 465 |
+
t.Logf("Network %s", network.Name)
|
| 466 |
+
for tc, testCase := range testCases {
|
| 467 |
+
t.Logf("testCase %d", tc)
|
| 468 |
t.Run(network.Name+testCase.name, func(t *testing.T) {
|
| 469 |
response, err := client.JSONRPCCall(network.URL, "eth_call", testCase.params...)
|
| 470 |
require.NoError(t, err)
|
| 471 |
+
if (testCase.expectedError != types.ErrorObject{}) {
|
| 472 |
+
require.NotNil(t, response.Error)
|
| 473 |
+
require.Nil(t, response.Result)
|
| 474 |
+
require.Equal(t, testCase.expectedError.Code, response.Error.Code)
|
| 475 |
+
require.Equal(t, testCase.expectedError.Message, response.Error.Message)
|
| 476 |
+
} else {
|
| 477 |
+
require.Nil(t, response.Error)
|
| 478 |
+
require.NotNil(t, response.Result)
|
| 479 |
+
}
|
| 480 |
})
|
| 481 |
}
|
| 482 |
}
|
|
|
|
| 625 |
txToMsg, err := sc.Increment(auth)
|
| 626 |
require.NoError(t, err)
|
| 627 |
|
| 628 |
+
// addresses the test needs to have balance
|
| 629 |
+
addressesToAddBalance := map[common.Address]*big.Int{
|
| 630 |
+
// add funds to address 0x111...111 which is the default address
|
| 631 |
+
// when estimating TXs without specifying the sender
|
| 632 |
+
common.HexToAddress("0x1111111111111111111111111111111111111111"): big.NewInt(3000000000000000),
|
| 633 |
+
|
| 634 |
+
// add funds to address 0x000...001
|
| 635 |
+
common.HexToAddress("0x1"): big.NewInt(1000),
|
| 636 |
+
}
|
| 637 |
+
|
| 638 |
+
for addr, value := range addressesToAddBalance {
|
| 639 |
+
nonce, err := ethereumClient.NonceAt(ctx, auth.From, nil)
|
| 640 |
+
require.NoError(t, err)
|
| 641 |
+
value := value
|
| 642 |
+
require.NoError(t, err)
|
| 643 |
+
tx = ethTypes.NewTx(ðTypes.LegacyTx{
|
| 644 |
+
Nonce: nonce,
|
| 645 |
+
To: state.Ptr(addr),
|
| 646 |
+
Value: value,
|
| 647 |
+
Gas: 24000,
|
| 648 |
+
GasPrice: gasPrice,
|
| 649 |
+
})
|
| 650 |
+
signedTx, err := auth.Signer(auth.From, tx)
|
| 651 |
+
require.NoError(t, err)
|
| 652 |
+
err = ethereumClient.SendTransaction(ctx, signedTx)
|
| 653 |
+
require.NoError(t, err)
|
| 654 |
+
err = operations.WaitTxToBeMined(ctx, ethereumClient, signedTx, operations.DefaultTimeoutTxToBeMined)
|
| 655 |
+
require.NoError(t, err)
|
| 656 |
+
|
| 657 |
+
balance, err := ethereumClient.BalanceAt(ctx, addr, nil)
|
| 658 |
+
require.NoError(t, err)
|
| 659 |
+
log.Debugf("%v balance: %v", addr.String(), balance.String())
|
| 660 |
+
}
|
| 661 |
|
| 662 |
type testCase struct {
|
| 663 |
name string
|
|
|
|
| 690 |
name: "with gasPrice set and without from address",
|
| 691 |
address: nil,
|
| 692 |
setGasPrice: true,
|
| 693 |
+
expectedError: nil,
|
| 694 |
+
},
|
| 695 |
+
{
|
| 696 |
+
name: "with gasPrice and value set and address with enough balance",
|
| 697 |
+
address: state.Ptr(auth.From),
|
| 698 |
+
value: state.Ptr(int64(1)),
|
| 699 |
+
setGasPrice: true,
|
| 700 |
+
expectedError: types.NewRPCError(-32000, "execution reverted"),
|
| 701 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 702 |
{
|
| 703 |
name: "with gasPrice and value set and address without enough balance",
|
| 704 |
address: state.Ptr(common.HexToAddress("0x1")),
|
|
|
|
| 713 |
setGasPrice: true,
|
| 714 |
expectedError: types.NewRPCError(-32000, "insufficient funds for transfer"),
|
| 715 |
},
|
| 716 |
+
// TODO = Review the test below in future versions of geth.
|
| 717 |
+
//
|
| 718 |
+
// Geth is returning -32000, "insufficient funds for transfer"
|
| 719 |
+
// zkEVM is returning 3, "execution reverted"
|
| 720 |
+
//
|
| 721 |
+
// Since the tx has value, the method increment is not payable
|
| 722 |
+
// and the default account has balance, the tx should revert
|
| 723 |
+
//
|
| 724 |
+
// {
|
| 725 |
+
// name: "with gasPrice and value set and without from address",
|
| 726 |
+
// address: nil,
|
| 727 |
+
// value: state.Ptr(int64(-1)),
|
| 728 |
+
// setGasPrice: true,
|
| 729 |
+
// expectedError: types.NewRPCError(-32000, "insufficient funds for transfer"),
|
| 730 |
+
// },
|
| 731 |
{
|
| 732 |
name: "without gasPrice set and address with enough balance",
|
| 733 |
address: state.Ptr(auth.From),
|
|
|
|
| 770 |
if testCase.value != nil {
|
| 771 |
v := *testCase.value
|
| 772 |
if v == -1 { //set the value as acc balance + 1 to force overflow
|
|
|
|
| 773 |
msg.Value = common.Big0.Add(balance, common.Big1)
|
| 774 |
} else {
|
| 775 |
msg.Value = big.NewInt(0).SetInt64(v)
|
|
|
|
| 780 |
msg.GasPrice = gasPrice
|
| 781 |
}
|
| 782 |
|
| 783 |
+
gas, err := ethereumClient.EstimateGas(ctx, msg)
|
| 784 |
+
t.Log("testCase: ", testCase.name)
|
| 785 |
+
t.Log("err: ", err)
|
| 786 |
+
t.Log("gas: ", gas)
|
| 787 |
if testCase.expectedError != nil {
|
| 788 |
rpcErr := err.(rpc.Error)
|
| 789 |
errMsg := fmt.Sprintf("[%v] expected: %v %v found: %v %v", network.Name, testCase.expectedError.ErrorCode(), testCase.expectedError.Error(), rpcErr.ErrorCode(), rpcErr.Error())
|
|
@@ -646,3 +647,106 @@
|
|
| 646 |
require.Equal(t, 0, big.NewInt(2).Cmp(value))
|
| 647 |
}
|
| 648 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 647 |
require.Equal(t, 0, big.NewInt(2).Cmp(value))
|
| 648 |
}
|
| 649 |
}
|
| 650 |
+
|
| 651 |
+
func TestCounterAndBlock(t *testing.T) {
|
| 652 |
+
if testing.Short() {
|
| 653 |
+
t.Skip()
|
| 654 |
+
}
|
| 655 |
+
|
| 656 |
+
var err error
|
| 657 |
+
err = operations.Teardown()
|
| 658 |
+
require.NoError(t, err)
|
| 659 |
+
|
| 660 |
+
defer func() { require.NoError(t, operations.Teardown()) }()
|
| 661 |
+
|
| 662 |
+
ctx := context.Background()
|
| 663 |
+
opsCfg := operations.GetDefaultOperationsConfig()
|
| 664 |
+
opsMan, err := operations.NewManager(ctx, opsCfg)
|
| 665 |
+
require.NoError(t, err)
|
| 666 |
+
err = opsMan.Setup()
|
| 667 |
+
require.NoError(t, err)
|
| 668 |
+
|
| 669 |
+
for _, network := range networks {
|
| 670 |
+
log.Debugf(network.Name)
|
| 671 |
+
client := operations.MustGetClient(network.URL)
|
| 672 |
+
auth := operations.MustGetAuth(network.PrivateKey, network.ChainID)
|
| 673 |
+
|
| 674 |
+
_, scTx, sc, err := CounterAndBlock.DeployCounterAndBlock(auth, client)
|
| 675 |
+
require.NoError(t, err)
|
| 676 |
+
|
| 677 |
+
logTx(scTx)
|
| 678 |
+
err = operations.WaitTxToBeMined(ctx, client, scTx, operations.DefaultTimeoutTxToBeMined)
|
| 679 |
+
require.NoError(t, err)
|
| 680 |
+
|
| 681 |
+
scReceipt, err := client.TransactionReceipt(ctx, scTx.Hash())
|
| 682 |
+
require.NoError(t, err)
|
| 683 |
+
|
| 684 |
+
scBlock, err := client.BlockByNumber(ctx, scReceipt.BlockNumber)
|
| 685 |
+
require.NoError(t, err)
|
| 686 |
+
|
| 687 |
+
count, ts, err := sc.GetCount(&bind.CallOpts{Pending: false, BlockNumber: scBlock.Number()})
|
| 688 |
+
require.NoError(t, err)
|
| 689 |
+
|
| 690 |
+
assert.Equal(t, 0, count.Cmp(big.NewInt(0)))
|
| 691 |
+
assert.Equal(t, ts.Uint64(), scBlock.Time())
|
| 692 |
+
|
| 693 |
+
const numberOfIncrements = 5
|
| 694 |
+
type result struct {
|
| 695 |
+
tx *types.Transaction
|
| 696 |
+
receipt *types.Receipt
|
| 697 |
+
block *types.Block
|
| 698 |
+
expectedCount *big.Int
|
| 699 |
+
}
|
| 700 |
+
|
| 701 |
+
results := make([]result, 0, numberOfIncrements)
|
| 702 |
+
for i := 0; i < numberOfIncrements; i++ {
|
| 703 |
+
tx, err := sc.Increment(auth)
|
| 704 |
+
require.NoError(t, err)
|
| 705 |
+
|
| 706 |
+
logTx(tx)
|
| 707 |
+
err = operations.WaitTxToBeMined(ctx, client, tx, operations.DefaultTimeoutTxToBeMined)
|
| 708 |
+
require.NoError(t, err)
|
| 709 |
+
|
| 710 |
+
receipt, err := client.TransactionReceipt(ctx, tx.Hash())
|
| 711 |
+
require.NoError(t, err)
|
| 712 |
+
|
| 713 |
+
block, err := client.BlockByNumber(ctx, receipt.BlockNumber)
|
| 714 |
+
require.NoError(t, err)
|
| 715 |
+
|
| 716 |
+
results = append(results, result{
|
| 717 |
+
tx: tx,
|
| 718 |
+
expectedCount: big.NewInt(int64(i) + 1),
|
| 719 |
+
receipt: receipt,
|
| 720 |
+
block: block,
|
| 721 |
+
})
|
| 722 |
+
}
|
| 723 |
+
|
| 724 |
+
const numberOfChecks = 2
|
| 725 |
+
|
| 726 |
+
// checks against first increment
|
| 727 |
+
for _, r := range results {
|
| 728 |
+
for i := 0; i < numberOfChecks; i++ {
|
| 729 |
+
count, ts, err = sc.GetCount(&bind.CallOpts{Pending: false, BlockNumber: r.block.Number()})
|
| 730 |
+
require.NoError(t, err)
|
| 731 |
+
assert.Equal(t, r.expectedCount.Uint64(), count.Uint64())
|
| 732 |
+
assert.Equal(t, r.block.Time(), ts.Uint64())
|
| 733 |
+
|
| 734 |
+
time.Sleep(time.Second)
|
| 735 |
+
}
|
| 736 |
+
}
|
| 737 |
+
|
| 738 |
+
latestIncrement := results[len(results)-1]
|
| 739 |
+
// checks against second increment with latest block
|
| 740 |
+
for i := 0; i < numberOfChecks; i++ {
|
| 741 |
+
latestBlock, err := client.BlockByNumber(ctx, nil)
|
| 742 |
+
require.NoError(t, err)
|
| 743 |
+
|
| 744 |
+
count, ts, err = sc.GetCount(&bind.CallOpts{Pending: false})
|
| 745 |
+
require.NoError(t, err)
|
| 746 |
+
assert.Equal(t, latestIncrement.expectedCount.Uint64(), count.Uint64())
|
| 747 |
+
assert.Equal(t, latestBlock.Time(), ts.Uint64())
|
| 748 |
+
|
| 749 |
+
time.Sleep(time.Second)
|
| 750 |
+
}
|
| 751 |
+
}
|
| 752 |
+
}
|
|
@@ -59,7 +59,7 @@
|
|
| 59 |
for _, gacc := range testCase.GenesisAccounts {
|
| 60 |
genesisAccounts[gacc.Address] = gacc.Balance.Int
|
| 61 |
}
|
| 62 |
-
require.NoError(t, opsman.SetGenesisAccountsBalance(genesisConfig.Genesis.
|
| 63 |
|
| 64 |
// Check initial root
|
| 65 |
require.NoError(t, opsman.CheckVirtualRoot(testCase.ExpectedOldRoot))
|
|
@@ -82,7 +82,7 @@
|
|
| 82 |
|
| 83 |
st := opsman.State()
|
| 84 |
|
| 85 |
-
// Check
|
| 86 |
l2Block, err := st.GetLastL2Block(ctx, nil)
|
| 87 |
require.NoError(t, err)
|
| 88 |
for addrStr, leaf := range testCase.ExpectedNewLeafs {
|
|
|
|
| 59 |
for _, gacc := range testCase.GenesisAccounts {
|
| 60 |
genesisAccounts[gacc.Address] = gacc.Balance.Int
|
| 61 |
}
|
| 62 |
+
require.NoError(t, opsman.SetGenesisAccountsBalance(genesisConfig.Genesis.RollupBlockNumber, genesisAccounts))
|
| 63 |
|
| 64 |
// Check initial root
|
| 65 |
require.NoError(t, opsman.CheckVirtualRoot(testCase.ExpectedOldRoot))
|
|
|
|
| 82 |
|
| 83 |
st := opsman.State()
|
| 84 |
|
| 85 |
+
// Check leaves
|
| 86 |
l2Block, err := st.GetLastL2Block(ctx, nil)
|
| 87 |
require.NoError(t, err)
|
| 88 |
for addrStr, leaf := range testCase.ExpectedNewLeafs {
|
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
DOCKERCOMPOSE := docker
|
| 2 |
DOCKERCOMPOSEAPPSEQ := zkevm-sequencer
|
| 3 |
DOCKERCOMPOSEAPPSEQV1TOV2 := zkevm-sequencer-v1tov2
|
| 4 |
DOCKERCOMPOSEAPPSEQSENDER := zkevm-sequence-sender
|
|
@@ -26,6 +26,7 @@
|
|
| 26 |
DOCKERCOMPOSEZKPROVER := zkevm-prover
|
| 27 |
DOCKERCOMPOSEPERMISSIONLESSDB := zkevm-permissionless-db
|
| 28 |
DOCKERCOMPOSEPERMISSIONLESSNODE := zkevm-permissionless-node
|
|
|
|
| 29 |
DOCKERCOMPOSEPERMISSIONLESSZKPROVER := zkevm-permissionless-prover
|
| 30 |
DOCKERCOMPOSENODEAPPROVE := zkevm-approve
|
| 31 |
DOCKERCOMPOSENODEAPPROVEV1TOV2 := zkevm-approve-v1tov2
|
|
@@ -62,6 +63,7 @@
|
|
| 62 |
|
| 63 |
RUNPERMISSIONLESSDB := $(DOCKERCOMPOSE) up -d $(DOCKERCOMPOSEPERMISSIONLESSDB)
|
| 64 |
RUNPERMISSIONLESSNODE := $(DOCKERCOMPOSE) up -d $(DOCKERCOMPOSEPERMISSIONLESSNODE)
|
|
|
|
| 65 |
RUNPERMISSIONLESSZKPROVER := $(DOCKERCOMPOSE) up -d $(DOCKERCOMPOSEPERMISSIONLESSZKPROVER)
|
| 66 |
|
| 67 |
RUNAPPROVE := $(DOCKERCOMPOSE) up -d $(DOCKERCOMPOSENODEAPPROVE)
|
|
@@ -101,6 +103,7 @@
|
|
| 101 |
|
| 102 |
STOPPERMISSIONLESSDB := $(DOCKERCOMPOSE) stop $(DOCKERCOMPOSEPERMISSIONLESSDB) && $(DOCKERCOMPOSE) rm -f $(DOCKERCOMPOSEPERMISSIONLESSDB)
|
| 103 |
STOPPERMISSIONLESSNODE := $(DOCKERCOMPOSE) stop $(DOCKERCOMPOSEPERMISSIONLESSNODE) && $(DOCKERCOMPOSE) rm -f $(DOCKERCOMPOSEPERMISSIONLESSNODE)
|
|
|
|
| 104 |
STOPPERMISSIONLESSZKPROVER := $(DOCKERCOMPOSE) stop $(DOCKERCOMPOSEPERMISSIONLESSZKPROVER) && $(DOCKERCOMPOSE) rm -f $(DOCKERCOMPOSEPERMISSIONLESSZKPROVER)
|
| 105 |
|
| 106 |
STOPAPPROVE := $(DOCKERCOMPOSE) stop $(DOCKERCOMPOSENODEAPPROVE) && $(DOCKERCOMPOSE) rm -f $(DOCKERCOMPOSENODEAPPROVE)
|
|
@@ -110,6 +113,9 @@
|
|
| 110 |
|
| 111 |
STOP := $(DOCKERCOMPOSE) down --remove-orphans
|
| 112 |
|
|
|
|
|
|
|
|
|
|
| 113 |
.PHONY: test-full-non-e2e
|
| 114 |
test-full-non-e2e: stop ## Runs non-e2e tests checking race conditions
|
| 115 |
$(RUNSTATEDB)
|
|
@@ -248,6 +254,17 @@
|
|
| 248 |
docker logs $(DOCKERCOMPOSEZKPROVER)
|
| 249 |
trap '$(STOP)' EXIT; MallocNanoZone=0 go test -count=1 -failfast -race -v -p 1 -timeout 2000s ../ci/e2e-group11/...
|
| 250 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 251 |
.PHONY: benchmark-sequencer-eth-transfers
|
| 252 |
benchmark-sequencer-eth-transfers: stop
|
| 253 |
$(RUNL1NETWORK)
|
|
@@ -364,7 +381,7 @@
|
|
| 364 |
$(STOPZKPROVER)
|
| 365 |
|
| 366 |
.PHONY: run-l1-explorer
|
| 367 |
-
run-l1-explorer: ## Runs L1 blockscan explorer
|
| 368 |
$(RUNEXPLORERL1DB)
|
| 369 |
$(RUNEXPLORERL1)
|
| 370 |
|
|
@@ -434,7 +451,7 @@
|
|
| 434 |
.PHONY: stop-seqsender-v1tov2
|
| 435 |
stop-seqsender-v1tov2: ## stops the sequencer sender
|
| 436 |
$(STOPV1TOV2SEQUENCESENDER)
|
| 437 |
-
|
| 438 |
.PHONY: run-sync
|
| 439 |
run-sync: ## runs the synchronizer
|
| 440 |
$(RUNSYNC)
|
|
@@ -498,7 +515,7 @@
|
|
| 498 |
.PHONY: stop-eth-tx-manager-v1tov2
|
| 499 |
stop-eth-tx-manager-v1tov2: ## Stops the eth tx manager service
|
| 500 |
$(STOPV1TOV2ETHTXMANAGER)
|
| 501 |
-
|
| 502 |
.PHONY: run-agg
|
| 503 |
run-agg: ## Runs the aggregator service
|
| 504 |
$(RUNAGGREGATOR)
|
|
@@ -540,7 +557,7 @@
|
|
| 540 |
$(RUNPERMISSIONLESSDB)
|
| 541 |
sleep 3
|
| 542 |
$(RUNPERMISSIONLESSZKPROVER)
|
| 543 |
-
|
| 544 |
|
| 545 |
PHONY: stop-permissionless-dependencies
|
| 546 |
stop-permissionless-dependencies: ## Stop the permissionless dependencies (db + prover) without the node
|
|
@@ -629,7 +646,7 @@
|
|
| 629 |
go run ./scripts/init_network/main.go .
|
| 630 |
|
| 631 |
.PHONY: show-logs
|
| 632 |
-
show-logs: ## Show logs for running docker
|
| 633 |
$(DOCKERCOMPOSE) logs
|
| 634 |
|
| 635 |
.PHONY: deploy-sc
|
|
@@ -669,7 +686,7 @@
|
|
| 669 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=stateInterface --dir=../sequencer --output=../sequencer --outpkg=sequencer --inpackage --structname=StateMock --filename=mock_state.go
|
| 670 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=txPool --dir=../sequencer --output=../sequencer --outpkg=sequencer --inpackage --structname=PoolMock --filename=mock_pool.go
|
| 671 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=Tx --srcpkg=github.com/jackc/pgx/v4 --output=../sequencer --outpkg=sequencer --structname=DbTxMock --filename=mock_dbtx.go
|
| 672 |
-
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=
|
| 673 |
|
| 674 |
.PHONY: generate-mocks-sequencesender
|
| 675 |
generate-mocks-sequencesender: ## Generates mocks for sequencesender , using mockery tool
|
|
@@ -685,10 +702,12 @@
|
|
| 685 |
.PHONY: generate-mocks-synchronizer
|
| 686 |
generate-mocks-synchronizer: ## Generates mocks for synchronizer , using mockery tool
|
| 687 |
## mocks for synchronizer
|
| 688 |
-
|
| 689 |
-
|
| 690 |
-
|
| 691 |
-
|
|
|
|
|
|
|
| 692 |
for i in l1RollupProducerInterface l1RollupConsumerInterface worker synchronizerProcessBlockRangeInterface workersInterface L1ParallelEthermanInterface; do \
|
| 693 |
camelcase=$$(echo $$i | sed 's/\([a-z0-9]\)\([A-Z]\)/\1_\2/g' | tr '[:upper:]' '[:lower:]') ; \
|
| 694 |
echo $$camelcase ; \
|
|
@@ -697,7 +716,7 @@
|
|
| 697 |
|
| 698 |
rm -Rf ../synchronizer/l2_sync/l2_sync_etrog/mocks
|
| 699 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --all --case snake --dir ../synchronizer/l2_sync/l2_sync_etrog --output ../synchronizer/l2_sync/l2_sync_etrog/mocks --outpkg mock_l2_sync_etrog ${COMMON_MOCKERY_PARAMS}
|
| 700 |
-
|
| 701 |
rm -Rf ../synchronizer/l2_sync/l2_shared/mocks
|
| 702 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --all --case snake --dir ../synchronizer/l2_sync/l2_shared --output ../synchronizer/l2_sync/l2_shared/mocks --outpkg mock_l2_shared ${COMMON_MOCKERY_PARAMS}
|
| 703 |
|
|
@@ -707,6 +726,9 @@
|
|
| 707 |
rm -Rf ../synchronizer/actions/elderberry/mocks
|
| 708 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --all --case snake --dir ../synchronizer/actions/elderberry --output ../synchronizer/actions/elderberry/mocks --outpkg mock_elderberry ${COMMON_MOCKERY_PARAMS}
|
| 709 |
|
|
|
|
|
|
|
|
|
|
| 710 |
|
| 711 |
|
| 712 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=Tx --srcpkg=github.com/jackc/pgx/v4 --output=../synchronizer/mocks --structname=DbTxMock --filename=mock_dbtx.go ${COMMON_MOCKERY_PARAMS}
|
|
@@ -723,7 +745,11 @@
|
|
| 723 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=poolInterface --dir=../gasprice --output=../gasprice --outpkg=gasprice --structname=poolMock --filename=mock_pool.go
|
| 724 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=ethermanInterface --dir=../gasprice --output=../gasprice --outpkg=gasprice --structname=ethermanMock --filename=mock_etherman.go
|
| 725 |
|
| 726 |
-
.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 727 |
generate-mocks-aggregator: ## Generates mocks for aggregator , using mockery tool
|
| 728 |
## mocks for the aggregator tests
|
| 729 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=stateInterface --dir=../aggregator --output=../aggregator/mocks --outpkg=mocks --structname=StateMock --filename=mock_state.go
|
|
@@ -733,7 +759,7 @@
|
|
| 733 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=aggregatorTxProfitabilityChecker --dir=../aggregator --output=../aggregator/mocks --outpkg=mocks --structname=ProfitabilityCheckerMock --filename=mock_profitabilitychecker.go
|
| 734 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=Tx --srcpkg=github.com/jackc/pgx/v4 --output=../aggregator/mocks --outpkg=mocks --structname=DbTxMock --filename=mock_dbtx.go
|
| 735 |
|
| 736 |
-
.PHONY: generate-mocks-state
|
| 737 |
generate-mocks-state: ## Generates mocks for state , using mockery tool
|
| 738 |
## mocks for the aggregator tests
|
| 739 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=storage --dir=../state --output=../state/mocks --outpkg=mocks --structname=StorageMock --filename=mock_storage.go --disable-version-string --with-expecter
|
|
@@ -745,6 +771,27 @@
|
|
| 745 |
run-benchmarks: run-db ## Runs benchmars
|
| 746 |
go test -bench=. ./state/tree
|
| 747 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 748 |
.PHONY: compile-scs
|
| 749 |
compile-scs: ## Compiles smart contracts, configuration in test/contracts/index.yaml
|
| 750 |
go run ./scripts/cmd... compilesc --input ./contracts
|
|
|
|
| 1 |
+
DOCKERCOMPOSE := docker compose -f docker-compose.yml
|
| 2 |
DOCKERCOMPOSEAPPSEQ := zkevm-sequencer
|
| 3 |
DOCKERCOMPOSEAPPSEQV1TOV2 := zkevm-sequencer-v1tov2
|
| 4 |
DOCKERCOMPOSEAPPSEQSENDER := zkevm-sequence-sender
|
|
|
|
| 26 |
DOCKERCOMPOSEZKPROVER := zkevm-prover
|
| 27 |
DOCKERCOMPOSEPERMISSIONLESSDB := zkevm-permissionless-db
|
| 28 |
DOCKERCOMPOSEPERMISSIONLESSNODE := zkevm-permissionless-node
|
| 29 |
+
DOCKERCOMPOSEPERMISSIONLESSNODEDAC := zkevm-node-forced-DAC
|
| 30 |
DOCKERCOMPOSEPERMISSIONLESSZKPROVER := zkevm-permissionless-prover
|
| 31 |
DOCKERCOMPOSENODEAPPROVE := zkevm-approve
|
| 32 |
DOCKERCOMPOSENODEAPPROVEV1TOV2 := zkevm-approve-v1tov2
|
|
|
|
| 63 |
|
| 64 |
RUNPERMISSIONLESSDB := $(DOCKERCOMPOSE) up -d $(DOCKERCOMPOSEPERMISSIONLESSDB)
|
| 65 |
RUNPERMISSIONLESSNODE := $(DOCKERCOMPOSE) up -d $(DOCKERCOMPOSEPERMISSIONLESSNODE)
|
| 66 |
+
RUNPERMISSIONLESSNODEDAC := $(DOCKERCOMPOSE) up -d $(DOCKERCOMPOSEPERMISSIONLESSNODEDAC)
|
| 67 |
RUNPERMISSIONLESSZKPROVER := $(DOCKERCOMPOSE) up -d $(DOCKERCOMPOSEPERMISSIONLESSZKPROVER)
|
| 68 |
|
| 69 |
RUNAPPROVE := $(DOCKERCOMPOSE) up -d $(DOCKERCOMPOSENODEAPPROVE)
|
|
|
|
| 103 |
|
| 104 |
STOPPERMISSIONLESSDB := $(DOCKERCOMPOSE) stop $(DOCKERCOMPOSEPERMISSIONLESSDB) && $(DOCKERCOMPOSE) rm -f $(DOCKERCOMPOSEPERMISSIONLESSDB)
|
| 105 |
STOPPERMISSIONLESSNODE := $(DOCKERCOMPOSE) stop $(DOCKERCOMPOSEPERMISSIONLESSNODE) && $(DOCKERCOMPOSE) rm -f $(DOCKERCOMPOSEPERMISSIONLESSNODE)
|
| 106 |
+
STOPPERMISSIONLESSNODEDAC := $(DOCKERCOMPOSE) stop $(DOCKERCOMPOSEPERMISSIONLESSNODEDAC) && $(DOCKERCOMPOSE) rm -f $(DOCKERCOMPOSEPERMISSIONLESSNODEDAC)
|
| 107 |
STOPPERMISSIONLESSZKPROVER := $(DOCKERCOMPOSE) stop $(DOCKERCOMPOSEPERMISSIONLESSZKPROVER) && $(DOCKERCOMPOSE) rm -f $(DOCKERCOMPOSEPERMISSIONLESSZKPROVER)
|
| 108 |
|
| 109 |
STOPAPPROVE := $(DOCKERCOMPOSE) stop $(DOCKERCOMPOSENODEAPPROVE) && $(DOCKERCOMPOSE) rm -f $(DOCKERCOMPOSENODEAPPROVE)
|
|
|
|
| 113 |
|
| 114 |
STOP := $(DOCKERCOMPOSE) down --remove-orphans
|
| 115 |
|
| 116 |
+
RUNDACDB := docker-compose up -d zkevm-data-node-db
|
| 117 |
+
STOPDACDB := docker-compose stop zkevm-data-node-db && docker-compose rm -f zkevm-data-node-db
|
| 118 |
+
|
| 119 |
.PHONY: test-full-non-e2e
|
| 120 |
test-full-non-e2e: stop ## Runs non-e2e tests checking race conditions
|
| 121 |
$(RUNSTATEDB)
|
|
|
|
| 254 |
docker logs $(DOCKERCOMPOSEZKPROVER)
|
| 255 |
trap '$(STOP)' EXIT; MallocNanoZone=0 go test -count=1 -failfast -race -v -p 1 -timeout 2000s ../ci/e2e-group11/...
|
| 256 |
|
| 257 |
+
.PHONY: test-e2e-group-cdk-validium-1
|
| 258 |
+
test-e2e-group-cdk-validium-1: stop ## Runs cdk-validium-1 e2e tests checking race conditions
|
| 259 |
+
$(RUNSTATEDB)
|
| 260 |
+
$(RUNPOOLDB)
|
| 261 |
+
$(RUNEVENTDB)
|
| 262 |
+
sleep 5
|
| 263 |
+
$(RUNZKPROVER)
|
| 264 |
+
docker ps -a
|
| 265 |
+
docker logs $(DOCKERCOMPOSEZKPROVER)
|
| 266 |
+
trap '$(STOP)' EXIT; MallocNanoZone=0 go test -count=1 -race -v -p 1 -timeout 2000s ../ci/e2e-group-cdk-validium-1/...
|
| 267 |
+
|
| 268 |
.PHONY: benchmark-sequencer-eth-transfers
|
| 269 |
benchmark-sequencer-eth-transfers: stop
|
| 270 |
$(RUNL1NETWORK)
|
|
|
|
| 381 |
$(STOPZKPROVER)
|
| 382 |
|
| 383 |
.PHONY: run-l1-explorer
|
| 384 |
+
run-l1-explorer: ## Runs L1 blockscan explorer
|
| 385 |
$(RUNEXPLORERL1DB)
|
| 386 |
$(RUNEXPLORERL1)
|
| 387 |
|
|
|
|
| 451 |
.PHONY: stop-seqsender-v1tov2
|
| 452 |
stop-seqsender-v1tov2: ## stops the sequencer sender
|
| 453 |
$(STOPV1TOV2SEQUENCESENDER)
|
| 454 |
+
|
| 455 |
.PHONY: run-sync
|
| 456 |
run-sync: ## runs the synchronizer
|
| 457 |
$(RUNSYNC)
|
|
|
|
| 515 |
.PHONY: stop-eth-tx-manager-v1tov2
|
| 516 |
stop-eth-tx-manager-v1tov2: ## Stops the eth tx manager service
|
| 517 |
$(STOPV1TOV2ETHTXMANAGER)
|
| 518 |
+
|
| 519 |
.PHONY: run-agg
|
| 520 |
run-agg: ## Runs the aggregator service
|
| 521 |
$(RUNAGGREGATOR)
|
|
|
|
| 557 |
$(RUNPERMISSIONLESSDB)
|
| 558 |
sleep 3
|
| 559 |
$(RUNPERMISSIONLESSZKPROVER)
|
| 560 |
+
|
| 561 |
|
| 562 |
PHONY: stop-permissionless-dependencies
|
| 563 |
stop-permissionless-dependencies: ## Stop the permissionless dependencies (db + prover) without the node
|
|
|
|
| 646 |
go run ./scripts/init_network/main.go .
|
| 647 |
|
| 648 |
.PHONY: show-logs
|
| 649 |
+
show-logs: ## Show logs for running docker
|
| 650 |
$(DOCKERCOMPOSE) logs
|
| 651 |
|
| 652 |
.PHONY: deploy-sc
|
|
|
|
| 686 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=stateInterface --dir=../sequencer --output=../sequencer --outpkg=sequencer --inpackage --structname=StateMock --filename=mock_state.go
|
| 687 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=txPool --dir=../sequencer --output=../sequencer --outpkg=sequencer --inpackage --structname=PoolMock --filename=mock_pool.go
|
| 688 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=Tx --srcpkg=github.com/jackc/pgx/v4 --output=../sequencer --outpkg=sequencer --structname=DbTxMock --filename=mock_dbtx.go
|
| 689 |
+
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=ethermanInterface --dir=../sequencer --output=../sequencer --outpkg=sequencer --inpackage --structname=EthermanMock --filename=mock_etherman.go
|
| 690 |
|
| 691 |
.PHONY: generate-mocks-sequencesender
|
| 692 |
generate-mocks-sequencesender: ## Generates mocks for sequencesender , using mockery tool
|
|
|
|
| 702 |
.PHONY: generate-mocks-synchronizer
|
| 703 |
generate-mocks-synchronizer: ## Generates mocks for synchronizer , using mockery tool
|
| 704 |
## mocks for synchronizer
|
| 705 |
+
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=EthermanFullInterface --dir=../synchronizer/common/syncinterfaces --output=../synchronizer --outpkg=synchronizer --structname=ethermanMock --filename=mock_etherman.go ${COMMON_MOCKERY_PARAMS}
|
| 706 |
+
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=StateFullInterface --dir=../synchronizer/common/syncinterfaces --output=../synchronizer --outpkg=synchronizer --structname=StateMock --filename=mock_state.go ${COMMON_MOCKERY_PARAMS}
|
| 707 |
+
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=EthTxManager --dir=../synchronizer/common/syncinterfaces --output=../synchronizer --outpkg=synchronizer --structname=ethTxManagerMock --filename=mock_ethtxmanager.go ${COMMON_MOCKERY_PARAMS}
|
| 708 |
+
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=PoolInterface --dir=../synchronizer/common/syncinterfaces --output=../synchronizer --outpkg=synchronizer --structname=poolMock --filename=mock_pool.go ${COMMON_MOCKERY_PARAMS}
|
| 709 |
+
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=Factory --srcpkg=github.com/0xPolygon/cdk-data-availability/client --output=../synchronizer --outpkg=synchronizer --structname=dataCommitteeClientFactoryMock --filename=mock_datacommitteeclientfactory.go ${COMMON_MOCKERY_PARAMS}
|
| 710 |
+
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=Client --srcpkg=github.com/0xPolygon/cdk-data-availability/client --output=../synchronizer --outpkg=synchronizer --structname=dataCommitteeClientMock --filename=mock_datacommitteeclient.go ${COMMON_MOCKERY_PARAMS}
|
| 711 |
for i in l1RollupProducerInterface l1RollupConsumerInterface worker synchronizerProcessBlockRangeInterface workersInterface L1ParallelEthermanInterface; do \
|
| 712 |
camelcase=$$(echo $$i | sed 's/\([a-z0-9]\)\([A-Z]\)/\1_\2/g' | tr '[:upper:]' '[:lower:]') ; \
|
| 713 |
echo $$camelcase ; \
|
|
|
|
| 716 |
|
| 717 |
rm -Rf ../synchronizer/l2_sync/l2_sync_etrog/mocks
|
| 718 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --all --case snake --dir ../synchronizer/l2_sync/l2_sync_etrog --output ../synchronizer/l2_sync/l2_sync_etrog/mocks --outpkg mock_l2_sync_etrog ${COMMON_MOCKERY_PARAMS}
|
| 719 |
+
|
| 720 |
rm -Rf ../synchronizer/l2_sync/l2_shared/mocks
|
| 721 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --all --case snake --dir ../synchronizer/l2_sync/l2_shared --output ../synchronizer/l2_sync/l2_shared/mocks --outpkg mock_l2_shared ${COMMON_MOCKERY_PARAMS}
|
| 722 |
|
|
|
|
| 726 |
rm -Rf ../synchronizer/actions/elderberry/mocks
|
| 727 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --all --case snake --dir ../synchronizer/actions/elderberry --output ../synchronizer/actions/elderberry/mocks --outpkg mock_elderberry ${COMMON_MOCKERY_PARAMS}
|
| 728 |
|
| 729 |
+
rm -Rf ../synchronizer/l1_check_block/mocks
|
| 730 |
+
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --all --case snake --dir ../synchronizer/l1_check_block --output ../synchronizer/l1_check_block/mocks --outpkg mock_l1_check_block ${COMMON_MOCKERY_PARAMS}
|
| 731 |
+
|
| 732 |
|
| 733 |
|
| 734 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=Tx --srcpkg=github.com/jackc/pgx/v4 --output=../synchronizer/mocks --structname=DbTxMock --filename=mock_dbtx.go ${COMMON_MOCKERY_PARAMS}
|
|
|
|
| 745 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=poolInterface --dir=../gasprice --output=../gasprice --outpkg=gasprice --structname=poolMock --filename=mock_pool.go
|
| 746 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=ethermanInterface --dir=../gasprice --output=../gasprice --outpkg=gasprice --structname=ethermanMock --filename=mock_etherman.go
|
| 747 |
|
| 748 |
+
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=dataAvailabilityProvider --dir=../etherman --output=../etherman --outpkg=etherman --structname=daMock --filename=mock_da.go
|
| 749 |
+
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=stateProvider --dir=../etherman --output=../etherman --outpkg=etherman --structname=stateMock --filename=mock_state.go
|
| 750 |
+
|
| 751 |
+
|
| 752 |
+
.PHONY: generate-mocks-aggregator
|
| 753 |
generate-mocks-aggregator: ## Generates mocks for aggregator , using mockery tool
|
| 754 |
## mocks for the aggregator tests
|
| 755 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=stateInterface --dir=../aggregator --output=../aggregator/mocks --outpkg=mocks --structname=StateMock --filename=mock_state.go
|
|
|
|
| 759 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=aggregatorTxProfitabilityChecker --dir=../aggregator --output=../aggregator/mocks --outpkg=mocks --structname=ProfitabilityCheckerMock --filename=mock_profitabilitychecker.go
|
| 760 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=Tx --srcpkg=github.com/jackc/pgx/v4 --output=../aggregator/mocks --outpkg=mocks --structname=DbTxMock --filename=mock_dbtx.go
|
| 761 |
|
| 762 |
+
.PHONY: generate-mocks-state
|
| 763 |
generate-mocks-state: ## Generates mocks for state , using mockery tool
|
| 764 |
## mocks for the aggregator tests
|
| 765 |
export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=storage --dir=../state --output=../state/mocks --outpkg=mocks --structname=StorageMock --filename=mock_storage.go --disable-version-string --with-expecter
|
|
|
|
| 771 |
run-benchmarks: run-db ## Runs benchmars
|
| 772 |
go test -bench=. ./state/tree
|
| 773 |
|
| 774 |
+
.PHONY: run-dac-db
|
| 775 |
+
run-dac-db: ## Suns the DAC DB
|
| 776 |
+
$(RUNDACDB)
|
| 777 |
+
|
| 778 |
+
.PHONY: stop-dac-db
|
| 779 |
+
stop-dac-db: ## Stops the DAC DB
|
| 780 |
+
$(STOPDACDB)
|
| 781 |
+
|
| 782 |
+
.PHONY: run-permissionless-dac
|
| 783 |
+
run-permissionless-dac: ## Runs a permissionless node that is forced to sync through DAC
|
| 784 |
+
$(RUNPERMISSIONLESSDB)
|
| 785 |
+
sleep 1
|
| 786 |
+
$(RUNPERMISSIONLESSZKPROVER)
|
| 787 |
+
$(RUNPERMISSIONLESSNODEDAC)
|
| 788 |
+
|
| 789 |
+
.PHONY: stop-permissionless-dac
|
| 790 |
+
stop-permissionless-dac: ## Stops the permissionless node that is forced to sync through DAC
|
| 791 |
+
$(STOPPERMISSIONLESSNODEDAC)
|
| 792 |
+
$(STOPPERMISSIONLESSZKPROVER)
|
| 793 |
+
$(STOPPERMISSIONLESSDB)
|
| 794 |
+
|
| 795 |
.PHONY: compile-scs
|
| 796 |
compile-scs: ## Compiles smart contracts, configuration in test/contracts/index.yaml
|
| 797 |
go run ./scripts/cmd... compilesc --input ./contracts
|
|
@@ -46,6 +46,7 @@
|
|
| 46 |
DefaultL1ZkEVMSmartContract = "0x8dAF17A20c9DBA35f005b6324F493785D239719d"
|
| 47 |
DefaultL1RollupManagerSmartContract = "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e"
|
| 48 |
DefaultL1PolSmartContract = "0x5FbDB2315678afecb367f032d93F642f64180aa3"
|
|
|
|
| 49 |
DefaultL1NetworkURL = "http://localhost:8545"
|
| 50 |
DefaultL1NetworkWebSocketURL = "ws://localhost:8546"
|
| 51 |
DefaultL1ChainID uint64 = 1337
|
|
@@ -263,7 +264,6 @@
|
|
| 263 |
if confirmationLevel == PoolConfirmationLevel {
|
| 264 |
return nil, nil
|
| 265 |
}
|
| 266 |
-
|
| 267 |
l2BlockNumbers := make([]*big.Int, 0, len(sentTxs))
|
| 268 |
for _, tx := range sentTxs {
|
| 269 |
// check transaction nonce against transaction reported L2 block number
|
|
@@ -662,3 +662,23 @@
|
|
| 662 |
panic(err)
|
| 663 |
}
|
| 664 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
DefaultL1ZkEVMSmartContract = "0x8dAF17A20c9DBA35f005b6324F493785D239719d"
|
| 47 |
DefaultL1RollupManagerSmartContract = "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e"
|
| 48 |
DefaultL1PolSmartContract = "0x5FbDB2315678afecb367f032d93F642f64180aa3"
|
| 49 |
+
DefaultL1DataCommitteeContract = "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE"
|
| 50 |
DefaultL1NetworkURL = "http://localhost:8545"
|
| 51 |
DefaultL1NetworkWebSocketURL = "ws://localhost:8546"
|
| 52 |
DefaultL1ChainID uint64 = 1337
|
|
|
|
| 264 |
if confirmationLevel == PoolConfirmationLevel {
|
| 265 |
return nil, nil
|
| 266 |
}
|
|
|
|
| 267 |
l2BlockNumbers := make([]*big.Int, 0, len(sentTxs))
|
| 268 |
for _, tx := range sentTxs {
|
| 269 |
// check transaction nonce against transaction reported L2 block number
|
|
|
|
| 662 |
panic(err)
|
| 663 |
}
|
| 664 |
}
|
| 665 |
+
|
| 666 |
+
// StartDACDB starts the data availability node DB
|
| 667 |
+
func (m *Manager) StartDACDB() error {
|
| 668 |
+
return StartComponent("dac-db", func() (bool, error) { return true, nil })
|
| 669 |
+
}
|
| 670 |
+
|
| 671 |
+
// StopDACDB stops the data availability node DB
|
| 672 |
+
func (m *Manager) StopDACDB() error {
|
| 673 |
+
return StopComponent("dac-db")
|
| 674 |
+
}
|
| 675 |
+
|
| 676 |
+
// StartPermissionlessNodeForcedToSYncThroughDAC starts a permissionless node that is froced to sync through the DAC
|
| 677 |
+
func (m *Manager) StartPermissionlessNodeForcedToSYncThroughDAC() error {
|
| 678 |
+
return StartComponent("permissionless-dac", func() (bool, error) { return true, nil })
|
| 679 |
+
}
|
| 680 |
+
|
| 681 |
+
// StopPermissionlessNodeForcedToSYncThroughDAC stops the permissionless node that is froced to sync through the DAC
|
| 682 |
+
func (m *Manager) StopPermissionlessNodeForcedToSYncThroughDAC() error {
|
| 683 |
+
return StopComponent("permissionless-dac")
|
| 684 |
+
}
|
|
@@ -111,7 +111,7 @@
|
|
| 111 |
return err
|
| 112 |
}
|
| 113 |
|
| 114 |
-
ethMan, err := etherman.NewClient(cfg.Etherman, cfg.NetworkConfig.L1Config)
|
| 115 |
if err != nil {
|
| 116 |
return err
|
| 117 |
}
|
|
@@ -183,7 +183,7 @@
|
|
| 183 |
// send to L1
|
| 184 |
firstSequence := seqs[0]
|
| 185 |
lastSequence := seqs[len(seqs)-1]
|
| 186 |
-
to, data, err := ethMan.BuildSequenceBatchesTxData(auth.From, seqs, uint64(lastSequence.LastL2BLockTimestamp), firstSequence.BatchNumber, auth.From)
|
| 187 |
if err != nil {
|
| 188 |
return err
|
| 189 |
}
|
|
|
|
| 111 |
return err
|
| 112 |
}
|
| 113 |
|
| 114 |
+
ethMan, err := etherman.NewClient(cfg.Etherman, cfg.NetworkConfig.L1Config, nil, nil)
|
| 115 |
if err != nil {
|
| 116 |
return err
|
| 117 |
}
|
|
|
|
| 183 |
// send to L1
|
| 184 |
firstSequence := seqs[0]
|
| 185 |
lastSequence := seqs[len(seqs)-1]
|
| 186 |
+
to, data, err := ethMan.BuildSequenceBatchesTxData(auth.From, seqs, uint64(lastSequence.LastL2BLockTimestamp), firstSequence.BatchNumber, auth.From, nil)
|
| 187 |
if err != nil {
|
| 188 |
return err
|
| 189 |
}
|
|
@@ -558,14 +558,13 @@
|
|
| 558 |
os.Exit(1)
|
| 559 |
}
|
| 560 |
|
| 561 |
-
client.
|
| 562 |
-
err = client.ExecCommand(datastreamer.CmdEntry)
|
| 563 |
if err != nil {
|
| 564 |
log.Error(err)
|
| 565 |
os.Exit(1)
|
| 566 |
}
|
| 567 |
|
| 568 |
-
printEntry(
|
| 569 |
return nil
|
| 570 |
}
|
| 571 |
|
|
@@ -597,35 +596,28 @@
|
|
| 597 |
Value: l2BlockNumber,
|
| 598 |
}
|
| 599 |
|
| 600 |
-
client.
|
| 601 |
-
err = client.ExecCommand(datastreamer.CmdBookmark)
|
| 602 |
if err != nil {
|
| 603 |
log.Error(err)
|
| 604 |
os.Exit(1)
|
| 605 |
}
|
| 606 |
-
|
| 607 |
-
firstEntry := client.Entry
|
| 608 |
printEntry(firstEntry)
|
| 609 |
|
| 610 |
-
client.
|
| 611 |
-
err = client.ExecCommand(datastreamer.CmdEntry)
|
| 612 |
if err != nil {
|
| 613 |
log.Error(err)
|
| 614 |
os.Exit(1)
|
| 615 |
}
|
| 616 |
-
|
| 617 |
-
secondEntry := client.Entry
|
| 618 |
printEntry(secondEntry)
|
| 619 |
|
| 620 |
i := uint64(2) //nolint:gomnd
|
| 621 |
for secondEntry.Type == state.EntryTypeL2Tx {
|
| 622 |
-
client.
|
| 623 |
-
err = client.ExecCommand(datastreamer.CmdEntry)
|
| 624 |
if err != nil {
|
| 625 |
log.Error(err)
|
| 626 |
os.Exit(1)
|
| 627 |
}
|
| 628 |
-
secondEntry =
|
| 629 |
printEntry(secondEntry)
|
| 630 |
i++
|
| 631 |
}
|
|
|
|
| 558 |
os.Exit(1)
|
| 559 |
}
|
| 560 |
|
| 561 |
+
entry, err := client.ExecCommandGetEntry(cliCtx.Uint64("entry"))
|
|
|
|
| 562 |
if err != nil {
|
| 563 |
log.Error(err)
|
| 564 |
os.Exit(1)
|
| 565 |
}
|
| 566 |
|
| 567 |
+
printEntry(entry)
|
| 568 |
return nil
|
| 569 |
}
|
| 570 |
|
|
|
|
| 596 |
Value: l2BlockNumber,
|
| 597 |
}
|
| 598 |
|
| 599 |
+
firstEntry, err := client.ExecCommandGetBookmark(bookMark.Encode())
|
|
|
|
| 600 |
if err != nil {
|
| 601 |
log.Error(err)
|
| 602 |
os.Exit(1)
|
| 603 |
}
|
|
|
|
|
|
|
| 604 |
printEntry(firstEntry)
|
| 605 |
|
| 606 |
+
secondEntry, err := client.ExecCommandGetEntry(firstEntry.Number + 1)
|
|
|
|
| 607 |
if err != nil {
|
| 608 |
log.Error(err)
|
| 609 |
os.Exit(1)
|
| 610 |
}
|
|
|
|
|
|
|
| 611 |
printEntry(secondEntry)
|
| 612 |
|
| 613 |
i := uint64(2) //nolint:gomnd
|
| 614 |
for secondEntry.Type == state.EntryTypeL2Tx {
|
| 615 |
+
entry, err := client.ExecCommandGetEntry(firstEntry.Number + i)
|
|
|
|
| 616 |
if err != nil {
|
| 617 |
log.Error(err)
|
| 618 |
os.Exit(1)
|
| 619 |
}
|
| 620 |
+
secondEntry = entry
|
| 621 |
printEntry(secondEntry)
|
| 622 |
i++
|
| 623 |
}
|
|
@@ -16,32 +16,32 @@
|
|
| 16 |
|
| 17 |
// GenesisTest2Actions change format from testvector to the used internaly
|
| 18 |
func GenesisTest2Actions(accounts []GenesisAccountTest) []*state.GenesisAction {
|
| 19 |
-
|
| 20 |
|
| 21 |
for _, acc := range accounts {
|
| 22 |
if len(acc.Balance) != 0 && acc.Balance != "0" {
|
| 23 |
-
|
| 24 |
Address: acc.Address,
|
| 25 |
Type: int(merkletree.LeafTypeBalance),
|
| 26 |
Value: acc.Balance,
|
| 27 |
})
|
| 28 |
}
|
| 29 |
if len(acc.Nonce) != 0 && acc.Nonce != "0" {
|
| 30 |
-
|
| 31 |
Address: acc.Address,
|
| 32 |
Type: int(merkletree.LeafTypeNonce),
|
| 33 |
Value: acc.Nonce,
|
| 34 |
})
|
| 35 |
}
|
| 36 |
if len(acc.Bytecode) != 0 {
|
| 37 |
-
|
| 38 |
Address: acc.Address,
|
| 39 |
Type: int(merkletree.LeafTypeCode),
|
| 40 |
Bytecode: acc.Bytecode,
|
| 41 |
})
|
| 42 |
}
|
| 43 |
for key, value := range acc.Storage {
|
| 44 |
-
|
| 45 |
Address: acc.Address,
|
| 46 |
Type: int(merkletree.LeafTypeStorage),
|
| 47 |
StoragePosition: key,
|
|
@@ -49,5 +49,5 @@
|
|
| 49 |
})
|
| 50 |
}
|
| 51 |
}
|
| 52 |
-
return
|
| 53 |
}
|
|
|
|
| 16 |
|
| 17 |
// GenesisTest2Actions change format from testvector to the used internaly
|
| 18 |
func GenesisTest2Actions(accounts []GenesisAccountTest) []*state.GenesisAction {
|
| 19 |
+
leaves := make([]*state.GenesisAction, 0)
|
| 20 |
|
| 21 |
for _, acc := range accounts {
|
| 22 |
if len(acc.Balance) != 0 && acc.Balance != "0" {
|
| 23 |
+
leaves = append(leaves, &state.GenesisAction{
|
| 24 |
Address: acc.Address,
|
| 25 |
Type: int(merkletree.LeafTypeBalance),
|
| 26 |
Value: acc.Balance,
|
| 27 |
})
|
| 28 |
}
|
| 29 |
if len(acc.Nonce) != 0 && acc.Nonce != "0" {
|
| 30 |
+
leaves = append(leaves, &state.GenesisAction{
|
| 31 |
Address: acc.Address,
|
| 32 |
Type: int(merkletree.LeafTypeNonce),
|
| 33 |
Value: acc.Nonce,
|
| 34 |
})
|
| 35 |
}
|
| 36 |
if len(acc.Bytecode) != 0 {
|
| 37 |
+
leaves = append(leaves, &state.GenesisAction{
|
| 38 |
Address: acc.Address,
|
| 39 |
Type: int(merkletree.LeafTypeCode),
|
| 40 |
Bytecode: acc.Bytecode,
|
| 41 |
})
|
| 42 |
}
|
| 43 |
for key, value := range acc.Storage {
|
| 44 |
+
leaves = append(leaves, &state.GenesisAction{
|
| 45 |
Address: acc.Address,
|
| 46 |
Type: int(merkletree.LeafTypeStorage),
|
| 47 |
StoragePosition: key,
|
|
|
|
| 49 |
})
|
| 50 |
}
|
| 51 |
}
|
| 52 |
+
return leaves
|
| 53 |
}
|
|
@@ -32,7 +32,7 @@
|
|
| 32 |
networkFlag = cli.StringFlag{
|
| 33 |
Name: config.FlagNetwork,
|
| 34 |
Aliases: []string{"net"},
|
| 35 |
-
Usage: "Load default network configuration. Supported values: [`
|
| 36 |
Required: false,
|
| 37 |
}
|
| 38 |
customNetworkFlag = cli.StringFlag{
|
|
|
|
| 32 |
networkFlag = cli.StringFlag{
|
| 33 |
Name: config.FlagNetwork,
|
| 34 |
Aliases: []string{"net"},
|
| 35 |
+
Usage: "Load default network configuration. Supported values: [`custom`]",
|
| 36 |
Required: false,
|
| 37 |
}
|
| 38 |
customNetworkFlag = cli.StringFlag{
|
|
@@ -77,7 +77,7 @@
|
|
| 77 |
}
|
| 78 |
|
| 79 |
func newEtherman(c config.Config) (*etherman.Client, error) {
|
| 80 |
-
etherman, err := etherman.NewClient(c.Etherman, c.NetworkConfig.L1Config)
|
| 81 |
if err != nil {
|
| 82 |
return nil, err
|
| 83 |
}
|
|
|
|
| 77 |
}
|
| 78 |
|
| 79 |
func newEtherman(c config.Config) (*etherman.Client, error) {
|
| 80 |
+
etherman, err := etherman.NewClient(c.Etherman, c.NetworkConfig.L1Config, nil, nil)
|
| 81 |
if err != nil {
|
| 82 |
return nil, err
|
| 83 |
}
|